1

All I can find in the PHP Manual for writing raw bytes to a file is fwrite. But when I use it (opening the file in b mode), it seems to write characters, not raw bytes.

Web searches turn up nothing useful.

I am using a large array of bytes in a file to hold bits, representing members of a large set. Since I manipulate only one bit at a time, I want to read and write the one raw byte that contains the current bit being changed.

The algorithm to do this set manipulationnis simple, but is not relevant to my question, which is: how to write one raw byte (or a larger fixed-length data block) into a file at an offset?

miken32
  • 42,008
  • 16
  • 111
  • 154
David Spector
  • 1,520
  • 15
  • 21
  • 1
    well a char is a raw byte my friend, and of course when you open file you will see characters :) try for example opening exe in notepad.. – Marko Mackic Jul 24 '16 at 20:20
  • You haven't tested it, right? The fwrite function makes the raw byte into a character. For example, writing (1 & 1), which is a single bit, is written as 31 (hex). I will ask in a PHP forum. – David Spector Jul 25 '16 at 10:48
  • 1
    @DavidSpector The expression `1 & 1` creates an integer which gets converted to the string **1** if you supply it to `fwrite()`. If you want to create a string containing the hex value 0x01, use `"\x01"`. [Reference](http://php.net/manual/en/language.types.string.php) – Kontrollfreak Jul 27 '16 at 11:55

2 Answers2

1

Use pack to correctly pack your data.

Example:

$a = 1 & 1;
$b = pack('i', $a);
file_put_contents('sample', $b);

Then view file sample with a hex editor.

vfsoraki
  • 2,186
  • 1
  • 20
  • 45
  • Fails to answer the question. file_put_contents works like fwrite, writing a STRING to a file. The question asks how to write a raw byte (an 8 bit unsigned integer) to a file. The question doesn't ask how to pack data. Bitwise operations pack data just fine. The question is how to write data without changing it into string characters. – David Spector Jul 25 '16 at 20:59
  • The output of `pack` is not string characters. Generally, write functions in PHP only deal with strings, no matter what you give it. Here you have to note that although the output of `pack` is string, but it does not contains charatcer "1", but the integer 1 itself. If you echo `$b` you will see "\x01" which means the byte you are looking for. Anyway, if you really want to write the integer 1 using `fwrite`-related function using bare strings, I think you are out of luck. – vfsoraki Jul 26 '16 at 05:21
  • I don't know how my answer did not help you, using `pack` before writing to a descriptor. But anyway, you got what you wanted, good luck. – vfsoraki Jul 27 '16 at 12:24
  • "Pack" seemed to be similar to using serialization: a hack to get binary file writing. I preferred the other answer that worked, using formatted file writing. It is just a preference, preferring common functions over rarer ones. Please don't take it personally. I appreciate your efforts, as I already said. Bye. – David Spector Jul 28 '16 at 13:54
1

I have received good help on this topic from the PHP News Group (mailing list). Although the PHP Manual appears to document fwrite as writing either character strings or binary data, in reality it will write only character strings. For example, if you write the integer or binary value 0x1 as a byte, the value 0x31 will actually be written, regardless of whether the 'b' mode is specified in fopen.

One solution is to use fprintf. For example, fprintf($Res, "%c", 0x1); will actually write the byte value 0x1 at the current offset in the file.

David Spector
  • 1,520
  • 15
  • 21