Recent

Author Topic: Large Byte array  (Read 5305 times)

fbartra

  • New member
  • *
  • Posts: 8
Large Byte array
« on: September 01, 2015, 01:27:12 pm »
I am trying to read large binary files > 1MB
I declare a dynamic array
but it gives me an error when I run it

"raised exception class "external SIGSEGV"
any suggestions will be appreciated

see a snip of my code below:


ByteRead    : array of byte;

  OpenDialog1.Filter := 'All Files|*.jpg;';//*.bmp';
  if OpenDialog1.Execute then
    begin

    filename := OpenDialog1.Filename;
 
  end;
  Fsize := filesize(filename);


  SetLength(ByteRead,FSize); <-- set array size


  fsIn := FileOpen(filename, FmOpenRead);
 
  count := FileRead(fsIn,ByteRead,Fsize);//NumberOfBytes);
  FileClose(fsIn);

  Message1.Width := 200;
  Message1.Caption := 'NO GPS INFO';

  GpsTagLoc := 0;
  WordComp := 0;
  for i := 0 to 500 do
  begin
    WordComp := ByteRead ;   <---- it fails right here

derek.john.evans

  • Guest
Re: Large Byte array
« Reply #1 on: September 01, 2015, 01:41:42 pm »
Why not use TMemoryStream?

**EDIT **
Code: [Select]
  var LBytes: PByte;
  with TMemoryStream.Create do begin
    try
      LoadFromFile('<<FILENAME>>');
      LBytes := Memory;
    finally
      Free;
    end;
  end; 
Or, TFileStream:
Code: [Select]
  var LBytes: array of Byte;   
  with TFileStream.Create('Unit1.pas', fmOpenRead) do begin
    try
      SetLength(LBytes, Size);
      ReadBuffer(LBytes[0], Size);
    finally
      Free;
    end;
  end;

I cant see the type for WordComp. If its a pointer, then you need to use:
Code: [Select]
WordComp := @ByteRead[0];
« Last Edit: September 01, 2015, 01:50:55 pm by derek.john.evans »

balazsszekely

  • Guest
Re: Large Byte array
« Reply #2 on: September 01, 2015, 01:56:30 pm »
In that for loop what are you trying to achieve exactly? What type is WordComp?

Code: [Select]
var
 ByteRead: array of byte;
 FS: TFileStream;
 I: Integer;
begin
  FS := TFileStream.Create(OpenDialog.FileName, fmOpenRead);
  try
    if FS.Size > 0 then
    begin
      SetLength(ByteRead, FS.Size);
      FS.Read(ByteRead[0], Fs.Size);
    end;
  finally
    FS.Free;
   end;
  for I := Low(ByteRead) to High(ByteRead) do
  begin
     //do whatever you have to do with ByteRead[I]
  end;
end;

PS:  @derek.john.evans I didn't see your edit with filestream.
« Last Edit: September 01, 2015, 01:58:21 pm by GetMem »

Gizmo

  • Hero Member
  • *****
  • Posts: 831
Re: Large Byte array
« Reply #3 on: September 01, 2015, 02:42:57 pm »
http://wiki.freepascal.org/File_Handling_In_Pascal#Binary_files :

Code: [Select]
var
  TotalBytesRead, BytesRead : Int64;
  Buffer : array [0..4095] of byte;  // or, array [0..1048575] of char for a 1Mb buffer
  FileStream : TFileStream;
 
try
  FileStream := TFileStream.Create;
  FileStream.Position := 0;  // Ensure you are at the start of the file
  while TotalBytesRead <= FileStream.Size do  // While the amount of data read is less than or equal to the size of the stream do
  begin
    BytesRead := FileStream.Read(Buffer,sizeof(Buffer));  // Read in 4096 of data
    inc(TotalBytesRead, BytesRead);                       // Increase TotalByteRead by the size of the buffer, i.e. 4096 bytes
    // Do something with Buffer data
  end;

mse

  • Sr. Member
  • ****
  • Posts: 286
Re: Large Byte array
« Reply #4 on: September 01, 2015, 03:07:32 pm »
  count := FileRead(fsIn,ByteRead,Fsize);//NumberOfBytes);
Probably
Code: [Select]
  count := FileRead(fsIn,ByteRead[0],Fsize);//NumberOfBytes);
(not tested).

fbartra

  • New member
  • *
  • Posts: 8
Re: Large Byte array
« Reply #5 on: September 01, 2015, 03:27:36 pm »
Sorry guys, I forgot to show "Wordcomp"
WordComp      : byte; <-- set as byte

then I compare byte by byte:
WordComp := ByteRead ;  <-- here I missed the in ByteRead

if I check the size of "ByteRead" array it shows '0'

is there a restriction on 'ByteRead' length? (which I defined as dynamic byte array)

Thank you again

Why not use TMemoryStream?

**EDIT **
Code: [Select]
  var LBytes: PByte;
  with TMemoryStream.Create do begin
    try
      LoadFromFile('<<FILENAME>>');
      LBytes := Memory;
    finally
      Free;
    end;
  end; 
Or, TFileStream:
Code: [Select]
  var LBytes: array of Byte;   
  with TFileStream.Create('Unit1.pas', fmOpenRead) do begin
    try
      SetLength(LBytes, Size);
      ReadBuffer(LBytes[0], Size);
    finally
      Free;
    end;
  end;

I cant see the type for WordComp. If its a pointer, then you need to use:
Code: [Select]
WordComp := @ByteRead[0];

fbartra

  • New member
  • *
  • Posts: 8
Re: Large Byte array
« Reply #6 on: September 01, 2015, 07:44:37 pm »
Derek:

thanks, it does work as you as you suggested

I am still would like to know why fileopen does not work?
it takes a very long time of trial and error to find the right function
I have been reading the lazarus manuals as well as using the internet
in general, is there a better way to find the proper functions?

Thanks again

Fausto

I am trying to read large binary files > 1MB
I declare a dynamic array
but it gives me an error when I run it

"raised exception class "external SIGSEGV"
any suggestions will be appreciated

see a snip of my code below:


ByteRead    : array of byte;

  OpenDialog1.Filter := 'All Files|*.jpg;';//*.bmp';
  if OpenDialog1.Execute then
    begin

    filename := OpenDialog1.Filename;
 
  end;
  Fsize := filesize(filename);


  SetLength(ByteRead,FSize); <-- set array size


  fsIn := FileOpen(filename, FmOpenRead);
 
  count := FileRead(fsIn,ByteRead,Fsize);//NumberOfBytes);
  FileClose(fsIn);

  Message1.Width := 200;
  Message1.Caption := 'NO GPS INFO';

  GpsTagLoc := 0;
  WordComp := 0;
  for i := 0 to 500 do
  begin
    WordComp := ByteRead ;   <---- it fails right here

derek.john.evans

  • Guest
Re: Large Byte array
« Reply #7 on: September 01, 2015, 08:11:12 pm »
I am still would like to know why fileopen does not work?

You found the quirk in the Pascal language that still catches me out. mse mentioned it a few posts back.

(CODE A) This code is _incorrect_:
Code: [Select]
FileRead(fsIn, ByteRead, Fsize)
(CODE B) This code is correct:
Code: [Select]
FileRead(fsIn, ByteRead[0], Fsize)
The problem is, they both compile. The other issue is, if you defined something like:
Code: [Select]
ByteRead: array[0..5000] of byte;
Then, both (CODE A) and (CODE B) will work.

So, it is possible to write old school Pascal, which will break when you update it to use dynamic arrays.

It has todo with low level Pascal functions which define untyped parameters: (FileRead is one of many)
Code: [Select]
Function FileRead (Handle : THandle; out Buffer; Count : longint) : Longint;
Note: The parameter Buffer has no type. I dont fully understand the internals, but, Ive learnt to see the warning signs.

Anytime I use a function which has a untyped parameter, It tells me to either take care, or use something else.
« Last Edit: September 01, 2015, 08:13:28 pm by derek.john.evans »

 

TinyPortal © 2005-2018