Search code examples
androidservicefileobserver

Android service file observer strange behavior


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.


Solution

  • 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.