Reputation: 628
I'm developing an application for embedded system running Linux.
In my case, I have a quite big file (compared to the capability of the system) as input. The file has a small header whose size is just a few hundred bytes. In my application, I need to remove that header from the file so the file will have no header and contain only relevant data. Normally, I'd implement like following (pseudo code):
char *input_file = "big_input.bin";
char *tmp_file1 = "header.bin";
char *tmp_file2 = "data.bin";
/* Copy the content of header from input file to tmp_file1 */
_copy_header(tmp_file1, input_file);
/* Copy the data from input file to tmp_file2 */
_copy_data(tmp_file2, input_file);
/* Rename temp file to input file */
unlink(input_file);
rename(tmp_file2, input_file);
The problem with this approach is that it creates a temporary file tmp_file2
whose size is almost as big as input file (because the header is very small). In my system, everything is stored on RAM, which is very limited. Creating a big temporary file causes an out-of-memory error.
So how can I avoid creating a big temporary file?
Upvotes: 3
Views: 550
Reputation: 70971
Open the same file twice, once for reading, once for writing.
Seek the read pointer behind the header.
Read from the read-pointer and write to the write-pointer.
Make sure the size you read and write at once is not larger than the header.
Cut off the header's size at the end of the file.
Upvotes: 6
Reputation: 1
Assuming you know the exact size of the header in advance, something like this should do it:
#define HEADER_SIZE 128
// size the buffer as appropriate for you RAM limits
char buffer[ 4096 ];
int fd = open( filename, O_RDWR );
size_t totalBytes = 0UL;
for ( ;; )
{
ssize_t bytes_read = pread( fd, buffer,
sizeof( buffer ), totalBytes + HEADER_SIZE );
if ( bytes_read <= 0L )
{
break;
}
pwrite( fd, buffer, bytes_read, totalBytes );
total_bytes += bytes_read;
}
ftruncate( fd, total_bytes );
close( fd );
You'll need to add the proper header files and some error checking.
Upvotes: 3
Reputation: 140226
In your case, you could
truncate
or ftruncate
as explained here: How to truncate a file in C?Upvotes: 1