Question: I am writing a program to reformat a DNS log file for insertion to a database. There is a possibility that the line currently being written to in the log file is incomplete. If it is, I would like to discard it.

I started off believing that the `eof` function might be a good fit for my application, however I noticed a lot of programmers dissuading the use of the `eof` function. I have also noticed that the `feof` function seems to be quite similar.

Any suggestions/explanations that you guys could provide about the side effects of these functions would be most appreciated, as would any suggestions for more appropriate methods!

**Edit:** I currently am using the `istream::peek` function in order to skip over the last line, regardless of whether it is complete or not. While acceptable, a solution that determines whether the last line is complete would be preferred.

The specific comparison I'm using is: `logFile.peek() != EOF`

Answer: 
I would consider using 

```
int fseek ( FILE * stream, long int offset, int origin );

```

with `SEEK_END`

and then 

```
long int ftell ( FILE * stream );

```

to determine the number of bytes in the file, and therefore - where it ends. I have found this to be more reliable in detecting the end of the file (in bytes).

Could you detect an (End of Record/Line) EOR marker (CRLF perhaps) in the last two or three bytes of the file? (3 bytes might be used for CRLF^Z...depends on the file type). This would verify if you have a complete last row

```
fseek (stream, -2,SEEK_END);
fread (2 bytes... etc

```

If you try to open the file with exclusive locks, you can detect (by the failure to open) that the file is in use, and try again in a second...(or whenever)
If you need to capture the file contents as the file is being written, it's much easier if you eliminate as many layers of indirection and buffering between your logic and the actual bytes of data in the file.

Do not use C++ IO streams of any type - you have no real control over them. Don't use `FILE *`-based functions such as `fopen()` and `fread()` - those are buffered, and even if you disable buffering there are layers of code between your code and the data that once again you can't control and don't know what's happening.

In a POSIX environment, you can use low-level C-style `open()` and `read()`/`pread()` calls. And use `fstat()` to know when the file contents have changed - you'll see the `st_size` member of the `struct stat` argument change after a call to `fstat()`.

You'd open the file like this:

```
int logFileFD = open( "/some/file/name.log", O_RDONLY );

```

Inside a loop, you could do something like this (error checking and actual data processing omitted):

```
size_t lastSize = 0;
while ( !done )
{
    struct stat statBuf;
    fstat( logFileFD, &statBuf );
    if ( statBuf.st_size == lastSize )
    {
        sleep( 1 ); // or however long you want
        continue;   // go to next loop iteration
    }
    // process new data - might need to keep some of the old data
    // around to handle lines that cross boundaries
    processNewContents( logFileFD, lastSize, statBuf.st_size );
}

```

`processNewContents()` could look something like this:

```
void processNewContents( int fd, size_t start, size_t end )
{
    static char oldData[ BUFSIZE ];
    static char newData[ BUFSIZE ];

    // assumes amount of data will fit in newData...
    ssize_t bytesRead = pread( fd, newData, start, end - start );

    // process the data that was read read here

    return;
}

```

You may also find that you need to add some code to `close()` then re-`open()` the file in case your application doesn't seem to be "seeing" data written to the file. I've seen that happen on some systems - the application somehow sees a cached copy of the file size somewhere while an `ls` run in another context gets the more accurate, updated size. If, for example, you know your log file is written to every 10-15 seconds, if you go 30 seconds without seeing any change to the file you know to try reopening the file.

You can also track the inode number in the `struct stat` results to catch log file rotation.

In a non-POSIX environment, you can replace `open()`, `fstat()` and `pread()` calls with the low-level OS equivalent, although [Windows provides](https://msdn.microsoft.com/en-us/library/634ca0c2.aspx) most of what you'd need. On Windows, `lseek()` followed by `read()` would replace `pread()`.