hakre
hakre

Reputation: 198247

How to change the first 512 bytes of a file?

I have got a large file in PHP of which I would like to replace the first 512 bytes with some other 512 bytes. Is there any PHP function that helps me with that?

Upvotes: 2

Views: 1268

Answers (1)

hakre
hakre

Reputation: 198247

If you want to optionally create a file and read and write to it (without truncating it), you need to open the file with the fopen() function in 'c+' mode:

$handle = fopen($filename, 'c+');

PHP then has the stream_get_contents() function which allows to read a chunk of bytes with a specific length (and from a specific offset in the file) into a string variable:

$buffer = stream_get_contents($handle, $length = 512, $offset = 0);

However, there is no stream_put_contents() function to write the string buffer back to the stream at a specific position/offset. A related function is file_put_contents() but it does not allow to write to a file-handle resource at a specific offset. But there is fseek() and fwrite() to do that:

$bytes_written = false;
if (0 === fseek($handle, $offset)) {
    $bytes_written = fwrite($handle, $buffer, $length);
}

Here is the full picture:

$handle = fopen($filename, 'c+');
$buffer = stream_get_contents($handle, $length = 512, $offset = 0);

// ... change $buffer ...

$bytes_written = false;
if (0 === fseek($handle, $offset)) {
    $bytes_written = fwrite($handle, $buffer, $length);
}
fclose($handle);

If the length of $buffer is not fixed this will not properly work. In that case it's better to work with two files and to use stream_copy_to_stream() as outlined in How to update csv column names with database table header or if the file is not large it is also possible to do that in memory:

$buffer = file_get_contents($filename);

// ... change $buffer ...

file_put_contents($filename, $buffer);

Upvotes: 10

Related Questions