4
  1. Open a file to read
  2. Read all the lines until EOF
  3. After 5 seconds, another contents are appended to the file
  4. Is it possible to read the newly written lines only until EOF again?
6
  • Programming languages have nothing to do with this. It's more of an operating system thing. The operating systems I know have no problems with this. Commented Dec 19, 2016 at 7:28
  • 2
    In C, or C++? They're very different languages, and goo C++11 code is more different from C than C++98 was. clearerr()? sleep()? Are you using cin and <iostream> etc? Or are you using <stdio.h>? Or <cstdio>? Commented Dec 19, 2016 at 7:36
  • @JonathanLeffler I am using <stdio.h>. Commented Dec 19, 2016 at 7:48
  • Then why is it tagged with C++? Commented Dec 19, 2016 at 7:52
  • @JonathanLeffler - "goo?" :) Commented Dec 19, 2016 at 8:58

4 Answers 4

1

You can clear the error and EOF indicators after reading EOF by using clearerr() or fseek(). You then have to decide how you are going to stop; maybe because of an unhandled signal (interrupt, etc). That leads to code like:

#include <stdio.h> #include <unistd.h> int main(int argc, char **argv) { if (argc != 2) { fprintf(stderr, "Usage: %s file\n", argv[0]); return 1; } FILE *fp = fopen(argv[1], "r"); if (fp == 0) { fprintf(stderr, "%s: failed to open file '%s' for reading\n", argv[0], argv[1]); return 1; } while (1) { char buffer[4096]; while (fgets(buffer, sizeof(buffer), fp) != 0) fputs(buffer, stdout); clearerr(fp); // fseek(fp, 0L, SEEK_CUR); sleep(5); } /*NOTREACHED*/ return 0; } 

Note that I wrote this as C code. However, it also compiles cleanly with a C++ compiler (even when it is set to be fussy).

$ g++ -O3 -g -std=c++11 -Wall -Wextra -Werror tf17.cpp -o tf17 $ gcc -O3 -g -std=c11 -Wall -Wextra -Werror tf19.c -o tf19 $ 

It was tested with a home-brew program called dribbler that writes messages slowly to a file.

Note that if you use fseek() to clear the EOF state, it is a good idea to seek zero bytes offset from the current position (SEEK_CUR). If you seek to the end, you might skip over data written since the program detected EOF. You could still run into problems if the file was truncated while you were reading it. The current position might be beyond the end of the truncated file.

Sign up to request clarification or add additional context in comments.

3 Comments

I tried to clear the EOF flag with seek in Python and Haskell, it does not work, not sure about C
@RandomB — C is not Python or Haskell. I don't know enough about either to pontificate, but AFAIK, both have their own I/O packages built atop the C library rather than just a thin cover layer interfacing to the C library. Consequently, different behaviour can be expected.
I will clarify my previous comment: sorry, it is not relevant, the effect was due to the tricky antivirus, I checked without it: it works as expected
1

This should work :

#include <stdio.h> #include <unistd.h>//To use the sleep function under UNIX int main(void) { FILE *f; int i; char line[1024]; f = fopen("yourfile", "r"); i = 0; while(fgets(line, 1024, f) != NULL) { //You can use your line here i++; //'i' is the number of line } fclose(f); sleep(5);//This line may change on windows f = fopen("yourfile", "r");//Reopen your file after modification while(i != 0)//We skip the line we already used { fgets(line, 1024, f); i--; } while(fgets(line, 1024, f) != NULL)//Here are the new line { //You can use your new line here } fclose(f); return 0; } 

4 Comments

How can we help if you downvote without saying anything ?
@ltega I think you got downvote because OP does not want to reopen a file.
@Itega I didn't downvote your answer. As Sumit Gemini said, I don't want to reopen the file. Thank you for the help though.
@MusieMeressa "I don't want to reopen the file" --> Why is this requirement not part of your post and instead only under one answer 8 hours afterwards? Makes one think that any answer will have new requirements on and on and on thus making the question even more unclear.
0

you can count the rows that you have already read and after 5 seconds you can read from next line.

void GotoLine(std::fstream& file, unsigned int num){ file.seekg(std::ios::beg); for(int i=0; i < num - 1; ++i){ file.ignore(std::numeric_limits<std::streamsize>::max(),'\n'); } string line; file>>line; cout<<line<<endl; //printing the new line data } 

Comments

0

There are some points that can help in reading from a file while it is actively being written to :-

  1. You can use mmap() with MAP_SHARED in both reader and writer. This way the reader will see the changes done by the writer practically immediately.
  2. Linux does not make any snapshot of the data in the file when you open the file, so you should see the changes that are being made in the file even if you just use read() and lseek().
  3. In order to determine whether a file was modified/opened/accessed/etc in Linux you can use inotify API. This allows you to make your process wait for an event you're interested in until it occurs (as opposed to polling it regularly).
  4. tail(), to find a tail of a file.

A small snippet can work for you: here in this example we are reading and writing at the same time.

read_pos = write_pos = 0; while ((val1 = fgetc(file_descriptor)) != EOF) { read_pos = ftell(file_descriptor); fseek(file_descriptor, write_pos, SEEK_SET); if (('a' <= val1) && (val1 <= 'z')) { fputc(val1 - 32, file_descriptor); } else { fputc(val1, file_descriptor); } write_pos = ftell(file_descriptor); fseek(file_descriptor, read_pos, SEEK_SET); } fclose(file_descriptor); return (0); } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.