Is there a simple way to insert something at the beginning of a text file using file streams? Because the only way I can think of, is to load a file into a buffer, write text-to-append and then write the buffer. I want to know if it is possible to do it without my buffer.
No, its not possible. You'd have to rewrite the file to insert text at the beginning.
EDIT: You could avoid reading the whole file into memory if you used a temporary file ie:
- Write the value you want inserted at the beginning of the file
- Read X bytes from the old file
- Write those X bytes to the new file
- Repeat 2,3 until you are done reading the old file
- Copy the new file to the old file.
There is no simple way, because the actual operation is not simple. When the file is stored on the disk, there are no empty available bytes before the beginning of the file, so you can't just put data there. There isn't an ideal generic solution to this -- usually, it means copying all of the rest of the data to move it to make room.
Thus, C makes you decide how you want to solve that problem.
Just wanted to counter some of the more absolute claims in here:
There is no way to append data to the beginning of a file.
Incorrect, there are, given certain constraints.
When the file is stored on the disk, there are no empty available bytes before the beginning of the file, so you can't just put data there.
This may be the case when dealing at the abstraction level of files as byte streams. However, file systems most often store files as a sequence of blocks, and some file systems allow a bit more free access at that level.
Linux 4.1+ (XFS) and 4.2+ (XFS, ext4) allows you to insert holes into files using fallocate
, given certain offset/length constraints:
Typically, offset and len must be a multiple of the filesystem logical block size, which varies according to the filesystem type and configuration.
Examples on StackExchange sites can be found by web searching for 'fallocate prepend to file'.
There is no way to append data to the beginning of a file.
The questioner also says that the only way they thought of solving the problem was by reading the whole file into memory and writing it out again. Here are other methods.
Write a placeholder of zeros of a known length. You can rewind the file handler and write over this data, so long as you do not exceed the placeholder size.
A simplistic example is writing the size of an unsigned int at the start that represents the count of lines that will follow, but will not be able to fill in until you reached the end and can rewind the file handler and rewrite the correct value.
Note: Some versions of 'C' on different platforms insist you finally place the file handler at the end of file before closing the file handler for this to work correctly.
Write the new data to a new file and then using file streams append the old data to the new file. Delete the old file and then rename the new file as the old file name. Do not use copy, it is a waste of time.
All methods have trade offs of disk size versus memory and CPU usage. It all depends on your application requirements.
Not strictly a solution, but if you're adding a short string to a long file, you can make a looping buffer of the same length you want to add, and sort of roll the extra characters out:
//also serves as the buffer; the null char gives the extra char for the begining
char insRay[] = "[inserted text]";
printf("inserting:%s size of buffer:%ld\n", insRay,sizeof(insRay));
//indecies to read in and out to the file
int iRead = sizeof(insRay)-1;
int iWrite = 0;
//save the input, so we only read once
int in = '\0';
do{
in = fgetc(fp);
//don't go to next char in the file
ungetc(in,fp);
if(in != EOF){
//preserve og file char
insRay[iRead] = in;
//loop
iRead++;
if(iRead == sizeof(insRay))
iRead = 0;
//insert or replace chars
fputc(insRay[iWrite],fp);
//loop
iWrite++;
if(iWrite == sizeof(insRay))
iWrite = 0;
}
}while(in != EOF);
//add buffer to the end of file, - the char that was null before
for(int i = 0; i < sizeof(insRay)-1;i++){
fputc(insRay[iWrite],fp);
iWrite++;
if(iWrite == sizeof(insRay))
iWrite = 0;
}
© 2022 - 2024 — McMap. All rights reserved.