0

I need to implement a service in android that must be able to monitor a folder to detect a certain file and read what it contains. I'm having a strange behavior with my code and I can't find the reason. This is my relevant code.

public void onCreate(){
    lectorFichCSV = new LectorFichCSV(); //object to read CSV files       
    ftpFileObserver = new FileObserver(filePath.getAbsolutePath()){
        public void onEvent(int event, String file) {
            if((FileObserver.CREATE & event) != 0){
                Log.i("INFO: ", filePath.getAbsolutePath() + "/" + file + " is created");
                if(file.substring(0,3).equals("RVE")){ //If file is created and the one I expect
                    try{
                        Log.i("INFO: ", "We have a RVE answer");
                        is = new FileInputStream(filePath + "/" + file);
                        lineaVent = lectorFichCSV.parseCSVFileAsList(is); //Get information in a list
                        //Get dao from ORMLite
                        dao = getHelper().getLineaVentDao();
                        Iterator<String[]> iterator = lineaVent.iterator();
                        if(iterator.hasNext()){
                            String[] aux = iterator.next();
                            Log.i("INFO:", "CodLineaVent "+aux[0]);
                            if(aux[2].equals("S")){
                                //Update DB information accordin to my file
                                UpdateBuilder<LineaVent, Integer> updateBuilder = dao.updateBuilder();
                                updateBuilder.where().eq("_id", aux[0]);
                                updateBuilder.updateColumnValue("valido", true);
                                updateBuilder.updateColumnValue("saldo", true);
                                updateBuilder.update();
                                lineaVent.clear();
                            }else if(aux[2].equals("N")){
                                UpdateBuilder<LineaVent, Integer> updateBuilder = dao.updateBuilder();
                                updateBuilder.where().eq("_id", aux[0]);
                                updateBuilder.updateColumnValue("saldo", false);
                                updateBuilder.update();
                                lineaVent.clear();
                            }
                            File fileToDel = new File(filePath + "/" + file);
                            fileToDel.delete();
                        }
                    }catch(FileNotFoundException e){
                        e.printStackTrace();
                    }catch(SQLException e){
                        e.printStackTrace();
                    }
                }

I debugged the code and sometimes is working and sometimes I get lineaVent.size() == 0. I'm going crazy with this, I'm thinking, is it possible that events occurs faster than the creation of my file? that would be the reason when I tried to parse my CSV file into my List object is size = 0? In that case I'm not getting any FileNotFoundException. Any help will be appreciate. Thank you.

mja
  • 135
  • 1
  • 16
acostela
  • 2,597
  • 3
  • 33
  • 50
  • From reading [the JavaDocs for `FileObserver`](https://developer.android.com/reference/android/os/FileObserver.html), I would expect that for a new file, I would get a `CREATE` event, zero or more `MODIFY` events, and a `CLOSE_WRITE` event. See what events you get, and if you do see a `CLOSE_WRITE`, you should probably delay your work until after that event. – CommonsWare Dec 02 '14 at 12:21
  • So the problem is that event occurs, I try to read the file and it's still empty? Must I nest another If inside that one for CLOSE_WRITE and after that read it? – acostela Dec 02 '14 at 12:24
  • "So the problem is that event occurs, I try to read the file and it's still empty?" -- that is my guess, yes. "Must I nest another If inside that one for CLOSE_WRITE and after that read it?" -- I cannot really answer that, as this is your app, not mine. – CommonsWare Dec 02 '14 at 12:25
  • I tried that and now it's working! Thank you very much If you want to put it as answer. Or I edit my question? – acostela Dec 02 '14 at 12:34

1 Answers1

1

I am not an expert with the inotify POSIX API that, IIRC, underlies FileObserver. However, given that there are separate events for CREATE, MODIFY, and CLOSE_WRITE, it stands to reason that the CREATE event is solely for file creation -- in other words, allocating a new entry in the filesystem for the file. That would either create an empty file, or perhaps a file with some initial load of bytes, but where other MODIFY calls might be needed to write out the full contents. CLOSE_WRITE would then be called to indicate that whoever was writing to the file has now closed their file handle.

Hence, if you are watching for some file to be created, to read it in, watch for CREATE, then watch for CLOSE_WRITE on that same file, and then try to read it, and see if that works better.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491