0

Well, I have a text file containing some lines. When I have to "delete" a line (known position from the start of the file) I read as many lines as needed until I reach the desired position; then from that position, I start to overwrite with the remaining lines after the line to be "deleted", now the old line is deleted. But my idea is to move the EOF to the old last line, which needs to be deleted as it's now a duplicate. How I print or move the EOF (End Of File)?

MattGeek
  • 593
  • 4
  • 10
  • 4
    http://pubs.opengroup.org/onlinepubs/9699919799/functions/truncate.html – Mat Apr 18 '18 at 15:30
  • @Mat How can that be helpful? – MattGeek Apr 18 '18 at 15:32
  • 4
    You truncate the file to be of size N - See [truncate/ftruncate](https://linux.die.net/man/2/truncate). – jweyrich Apr 18 '18 at 15:33
  • @jweyrich but will truncate create a new file? – MattGeek Apr 18 '18 at 15:34
  • Nope. Same file. Truncation will just decrease the file size to the specified size. – jweyrich Apr 18 '18 at 15:35
  • 1
    The easy way is to `mmap` the entire file (i.e. not use `FILE *` functions like `fgets`). Do the elide in the mapped buffer (e.g. `memcpy(bufp + offset_of_line_to_elide,buf_p + offset_of_next_line,length_of_remainder_of_file)` and then use `truncate/ftruncate` at the end. See my answer here: https://stackoverflow.com/questions/33616284/read-line-by-line-in-the-most-efficient-way-platform-specific/33620968#33620968 for some details on how to do the mapping vs `fgets` – Craig Estey Apr 18 '18 at 15:36
  • My file is already open in r+ mode, is that alright or should close the file, reopen it in writing mode and then use that function? – MattGeek Apr 18 '18 at 15:38
  • 5
    Such operations are usually performed by writing/renaming a temp file. One resons why that is a better option is that, with care, it is possible to ensure that the operation can be 'atomic', ie. no matter when it is interupted, (eg. power fail), it is always possible to recover a valid file, either the original or one with the entry successfully deleted. – Martin James Apr 18 '18 at 15:39
  • @CraigEstey Sorry, but I don't want to use dinamic memory. – MattGeek Apr 18 '18 at 15:40
  • Mapping the file isn't using dynamic memory [as in a huge `malloc` of the entire file contents]. It's a pretty standard way to access the file. And, although you _can_ do this with `fread/fwrite`, it will be potentially a lot slower because you'll have to copy the file in chunks and be doing a lot of `fseek` operations. At that point, I'd switch to `read/write/lseek` syscalls. – Craig Estey Apr 18 '18 at 15:45
  • @MartinJames is right. A more fault tolerant solution is to create a new file, complete the operation on it, save it, rename old to temp, rename new to old, delete temp. – chux - Reinstate Monica Apr 18 '18 at 16:24
  • 3
    You can also use `ftruncate()`, see http://pubs.opengroup.org/onlinepubs/009604499/functions/ftruncate.html, that executes same operation on a valid file open for writing. Anyway, as you have already been warned, consider that executing such operations on files can lead to loss of data in case of failure. – Frankie_C Apr 18 '18 at 16:35

0 Answers0