Byte Position: file_get_contents vs fopen

I need some data from a specific byte in a range in a binary.
(concatenated jpegs, don't ask ...)

So, I have offset and length data from an external API.
(I would suggest that these are byte positions)

What works:

 $fileData = file_get_contents($binaryFile); $imageData = substr($fileData, $offset, $length); 

But I would prefer not to load the full file into memory, and so I tried fopen :

 $handle = fopen($binaryFile, 'rb'); fseek($handle, $offset); $imageData = fgets($handle, $length); 

But that does not work. The data block is not valid image data.
Therefore, I assume that I misunderstood the position of fopen .

Any ideas on how positions differ in substr vs fopen ?

+5
source share
2 answers

You wrote

The data block is not valid image data.

"image data" - but in your code you call fgets() to read that data. This is wrong, since the image is binary data, not a text file, so you do not want it to read it line by line ( docs ):

fgets - gets the string from file pointer

This means that fgets() stop reading from the file as soon as it detects that it considers the end-of-line marker, which usually means stopping earlier and reading less than $length , since there is a fairly low chance that such a byte is not in binary sequence.

So fgets() wrong method to use, and this is the main problem. Instead, you should choose a less clever fread() (which doesn't know about lines, etc. And just reads what you said). Finally, you should fclose() process when done. And, of course, you should always check for errors starting with fopen() :

 if ($handle = fopen($binaryFile, 'rb')) { if (fseek($handle, $offset) === 0) { $imageData = fread($handle, $length); if ($imageData === false) { // error handling - failed to read the data } } else { // error handling - seek failed } fclose($handle); } else { // error handling - can't open file } 

Therefore, always use the right tool for the task, and if you do not know what the given method / function does , there is always a good documentation to look.

+4
source

You can also use file_get_contents . See this simple line:

 imageData = file_get_contents($binaryFile, null, null, 0, $length); 

And here is the documentation of file_get_contents .

+2
source

Source: https://habr.com/ru/post/1272584/


All Articles