-1

I'm working with stream files, but "out of memory" error occurred. I think I must read stream, byte by byte. Then I load a file with this method:

fs := TFileStream.Create("c:\a\a.avi", fmOpenRead or fmShareDenyWrite) ;

Next i reset stream position:

fs.positon:=0;

Then i'm trying to read first byte of stream:

var
oneByte:byte;
begin 
fs.Read(oneByte,2);

but it doesn't work properly. Where is my mistake?

Hosain
  • 41
  • 2
  • 3
  • Byte by byte is not going to be much better than reading the entire file in one go. It will take forever to read it byte by byte. You need the middle ground. Read larger sized pieces. A few MBs at a time. – David Heffernan Jan 16 '16 at 08:14
  • @DavidHeffernan AFAIK `TFileStream` uses buffered access to file. Still reading byte to byte may not be most suitable option, but that depends on what has to be done with read data. – Dalija Prasnikar Jan 16 '16 at 08:22
  • 1
    @Dalija You are quite wrong. It has no buffer. Each call to Read is a call to win32 ReadFile. Immensely inefficient. Hence the need for things like this: http://stackoverflow.com/a/5639712/505088 – David Heffernan Jan 16 '16 at 08:24
  • @DavidHeffernan I think it is opened in buffered mode, cannot check now though. – Dalija Prasnikar Jan 16 '16 at 08:28
  • @Dalija There's nothing to check. Buffered mode doesn't deal with the actual issue which is the overhead of a system call. And in fact the file is not opened buffered. Whilst Windows buffers the data itself, often cached in memory, calls to ReadFile have a serious overhead. File handles are kernel objects after all. Still, if you want to check it's simple enough. Read a large file in one go, or byte by byte. – David Heffernan Jan 16 '16 at 08:28
  • @DavidHeffernan You are right on that one. – Dalija Prasnikar Jan 16 '16 at 08:29
  • 1
    *Where is my mistake?* You mean other than the obvious one, of trying to read two bytes of data into a variable of one byte in size? (The error is even more foolish than that; you name the variable **one**Byte, and then try to read **2** byes of data into it: `fs.Read(**oneByte**, **2**);` – Ken White Jan 16 '16 at 21:08

1 Answers1

5

Byte size is 1 not 2

fs.Read(oneByte, 1);

Such errors can easily be prevented by using SizeOf() function

fs.Read(oneByte, SizeOf(oneByte));

On another note, Read returns the number of bytes read to indicate whether or not the entire read succeeded. You would be expected to check that return value to deal with errors.

The preferred idiom is to use ReadBuffer instead. That will call Read and in case of error raise an exception.

As @David Heffernan pointed out reading file stream byte by byte is not the most efficient way. Take a look at Buffered files (for faster disk access)

Community
  • 1
  • 1
Dalija Prasnikar
  • 27,212
  • 44
  • 82
  • 159