Simple C fread and fseek to bulk read lines separated with a \n

Here is simple file chunker that writes only complete complete records read in from a file to another file. For example, there are JSON records delimited with a '\' character and because they are variable in size, the buffer size WILL not align and therefore needs us to read X bytes, then walk backwards until we find the last complete record.

This requires us to use fseek (fseek(fp,i-tmp_bytes_read,SEEK_CUR);) to re-adjust the filepointer such that the next read will begin at the correct point.

#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#define LOGNAME "log.txt"
#define OUTNAME "out.txt"
int main(int argc, char **argv)
{

        FILE *fp;
        FILE *fpout;
        char buffer[getpagesize()];
        int buff_size = sizeof(buffer);
        memset(buffer, 0, buff_size);
        printf("page size: %ld\n", getpagesize());
       
        size_t bytes_read = 0;

        // Get input filesize
        struct stat file_info = { 0 };
        stat(LOGNAME, &file_info);
        printf("file size: %ld\n", file_info.st_size);
       
        // Open file for both reading and writing
        fp = fopen(LOGNAME, "r");
        fpout = fopen(OUTNAME, "w");

        // Read data
        int i = 0;
        size_t tmp_bytes_read = 0;
        while ( (bytes_read < (file_info.st_size))) {
               
                tmp_bytes_read = fread(buffer, 1, buff_size, fp);
                for (i = tmp_bytes_read; i != 0; i--) {

                        if ((buffer[i] == '\n')) {
                                break;
                        } else if(feof(fp)) {
                                break;
                        }
                }
               
                fseek(fp,i-tmp_bytes_read,SEEK_CUR);
                fwrite(buffer,1,i,fpout);
                bytes_read += i;
               
        }

        printf("\nsize overall read: %ld\n",bytes_read);
        fclose(fp);
        fclose(fpout);
        return 0;
}

Blog tags: 

Add new comment

Filtered HTML

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd> <python> <c>
  • Lines and paragraphs break automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
By submitting this form, you accept the Mollom privacy policy.