-2

I am reading a ~2mb CSV file of about 40000 lines and each line defines an object in a list and I need to reflect any changes on the input file to my list and vice-versa... Say if I modify a line on the input file I need to update my object on the list and a modification on the object will be reflected to file immediately. I know it can be done in an infinite while loop but its quite waste of resources and sounds ridiculous. Is there a function or an update flag which I can check or some other approach that I read the file only when updated? I am coding in C++ by the way :)

EDITED

I played a while with the code @Jake proposed and come out with a working solution. Here is a better question for you then... the code I wrote seems working instantly sometimes but sometimes it does not updates the modifications I made to file as I save the file and only after saving file 3 or 5 times more I see the update? What could be the reason for that? Can I improve this solution any further?

#include <iostream>
#include <fstream>
#include <sys/stat.h>

#define INFILE "test.txt"

using namespace std;

__time_t getFileModifyTime(char *filePath)
{
    struct stat attrib;
    stat(filePath, &attrib);
    __time_t date = attrib.st_mtime ;
    return date;
}

int main(){

    ifstream infile;
    infile.open (INFILE);
    string currentLine;

    __time_t lastUpdateTime = 0;


    while(true)     // start an infinite loop
    {
        if(lastUpdateTime != getFileModifyTime(INFILE)) {

            cout << "last update time  : " << lastUpdateTime << endl;
            cout << "modification time : " << getFileModifyTime(INFILE) << endl;

            infile.close();
            infile.open (INFILE);

            while (getline(infile, currentLine)) {
                cout << currentLine << endl;
            }    
        }
        lastUpdateTime = getFileModifyTime(INFILE);
    }

    return  0;
}
alios
  • 43
  • 9
  • 1
    A bit of a hack, but if no one else has a good way to accomplish this, you could probably make it happen via the [dropbox api](https://stackoverflow.com/questions/21841362/dropbox-sync-api-for-c). Or you could make a copy of the file and then run a [diff](https://stackoverflow.com/questions/1451694/is-there-a-way-to-diff-files-from-c) in your loop (though that would be costly, as you noted). – scohe001 Dec 08 '17 at 00:52
  • 2
    Nope, there's nothing like that in the C++ standard. There may be some operating system-specific features that can be used. On Linux, for examples, there's the [inotify API](http://manpages.courier-mta.org/htmlman7/inotify.7.html). – Sam Varshavchik Dec 08 '17 at 00:55
  • 2
    There are dozens of ways to accomplish this, which makes your question far too broad. You don't even mention what OS you're running on, but calls to the OS to detect file changes would be among some of the best solutions. You need to make an effort to solve this and come back with a better question. – Carey Gregory Dec 08 '17 at 00:55
  • I am working on Linux now but I thought there might be a system independent solution. And using a system call did not ever come to my mind, I am going to check for it. – alios Dec 08 '17 at 01:40
  • @Carey I made some effort for you :) But it does not updates sometimes as I mentioned above, do you have an idea why it might be? And to be precise I am working on 64 bit Ubuntu 16.04 – alios Dec 08 '17 at 20:51

1 Answers1

2

With Linux you can use the following code to tell if a file was updated:

auto getFileCreationTime(char *filePath)
{
    struct stat attrib;
    stat(filePath, &attrib);
    char date[10];
    strftime(date, 10, "%d-%m-%y", gmtime(&(attrib.st_ctime)));
    return date;
}

So using threads and a while statement you could do something like this

auto mod_time_first = getLastTime();
while(true)
{
    if(mod_time_first == getLastTime()) {} // Do something now
    mod_time_first = getLastTime();
}
Jake Freeman
  • 1,700
  • 1
  • 8
  • 15
  • nice approach indeed way better than keep reading the whole file repeatedly... I'll try that. – alios Dec 08 '17 at 01:53