Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
559 views
in Technique[技术] by (71.8m points)

c++ - Truncate or resize a file in order to modify its end

I have a FILE* file that holds some binary data. Let's say that this data are a list of double and that the last entry is a string that describes what are those double. I want to modify this string (the new string might be shorter). So first i delete the old string. I need to find the starting point of the string :

fseek(file,-size(sring.size()),SEEK_END);

and then what should i do ? i found Delete End of File link but i don't know which one to use... Once the file is re-sized, can i simply write my new string using fwrite ?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Neither FILE* nor iostream support truncation. If you want to edit a file so that the new file is shorter than the old, you have two solutions:

  • The usual solution is to copy the original file into a new file, making any changes as you go. When finished, close the new file, verify that there are no errors (an important point), then delete the original file and rename to new file to have the original name. This may cause problems on Unix systems if there were hard links to the original file. (Typically, this isn't an issue, since everyone uses soft links now. If it is, you should stat the original, and if the st_nlink field is greater than 1, copy the new file onto the original, and then delete the new file.) On the other hand, it is the most generic option; it works for all types of modifications, anywhere in the file.

  • There are usually system specific functions at the lower level to truncate a file. Under Unix, this is ftruncate. But you'll need to find the byte count where you want to truncate first; ftruncate requires an open file, but it won't truncate at the current position in the file. So you'll have to 1) find the start of this last line in the file, 2) seek to it, 3) write the new value, 4) call ftell (or ftello, if the length can be too large to fit on a long) to find the new end position. At this point, you have the problem of synchronizing your FILE* with the lower level; personally, I'd fclose the file, then reopen it with open, and do the ftruncate on the file descripter from this open. (In fact, personally, I'd do the entire job using open, read, lseek, write, ftruncate and close. And maybe stat to find out the file length up front. If you don't have to translate the doubles, there's really nothing that FILE* adds.

As a general rule, I'd go with the first solution, and only try the second if it turns out to be too slow. (If the file contains a couple of billion doubles, for example, copying them will take some time.)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...