Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have to replace on a Linux web server, the first 128 bytes of some binary files.

The files have a size of ~ 5Gb and I just have to rewrite the header bytes. What would be the best approach to do this using Linux native commands or even PHP?

share|improve this question
up vote 10 down vote accepted

Simply open the file in "append" or similar mode, seek to position 0, then write your data.


"Linux native commands": the syscalls (or their libc wrappers) are as close as you can get.

#include <fcntl.h>
#include <unistd.h>

void main() {
    char buf[128] = "this and that";
    int fd = open("file", O_WRONLY);
    lseek(fd, 0, SEEK_SET);
    write(fd, &buf, sizeof(buf));
    close(fd);
}

PHP:

<?php
$buf = "this and that";
$fh = fopen("file", "a" "r+");
fseek($fh, 0);
fwrite($fh, $buf);
fclose($fh);
share|improve this answer
1  
It would have been nice if I could test the php solution, but as it is, doesn't work (If you have opened the file in append (a or a+) mode, any data you write to the file will always be appended, regardless of the file position, and the result of calling fseek() will be undefined. ) – Mark Mar 20 '12 at 12:15
1  
@Xander: That is an ... interesting design decision from PHP's side. Try opening the file as c or r+, then. (Is this actually documented anywhere?) – grawity Mar 20 '12 at 13:39
1  
Ah, I found it under fseek(). Sigh. – grawity Mar 20 '12 at 13:47
1  
@Xander: I suggest encoding them with Base64 (PHP has base64_encode and base64_decode for that) and sending them over POST. Don't forget proper authentication! – André Paramés Mar 20 '12 at 17:29
1  
@grawity That's not PHP's fault, "a" is equivalent to opening with O_APPEND, and is documented in the equivalent C functions (both open and fopen) – Random832 Mar 20 '12 at 19:34

The dd is a simple approach.

dd if=128bytefile of=videofiletofix.mkv bs=128 count=1 conv=notrunc

So this will take the first 128 bytes of a file called 128bytefile and overwrite the first 128 bytes of a file called videofiletofix.mkv.

The bs parameter says to copy 128 bytes at a time, and the count parameter says to copy one such 128 byte block. The conv=notrunc parameter is important — without it, dd will truncate the output file to the length of the copied data (here, 128 bytes), which is most definitely not what you want.

share|improve this answer
    
nice solution Paul, thanks for your help. I would rise a point but I'm too new around and the system does not allow :) – Mark Mar 20 '12 at 12:07
    
This is how I'd do it, excellent answer. – Rob Mar 20 '12 at 14:17
1  
@Xander: You can do something like dd if=localfile bs=128 count=1 | ssh server 'dd of=videofile conv=notrunc'. However, why not just copy the 128-byte file to the server first? – Ilmari Karonen Mar 20 '12 at 14:46
    
@Xander: You could always download dd for Windows and use it to extract the first 128 bytes. (Just use the same command as in the answer, but with a non-existent file as the target.) – Ilmari Karonen Mar 20 '12 at 15:00
    
@Xander: 1. Anything that can transfer binary files is fine. 2. Use the dd command given in the answer. Just to be safe, you may want to make a backup copy of the target file first, at least until you're sure you've got the hang of it. – Ilmari Karonen Mar 20 '12 at 15:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .