【问题标题】:Android service file observer strange behaviorAndroid服务文件观察者奇怪的行为
【发布时间】:2014-12-02 12:17:40
【问题描述】:

我需要在 android 中实现一项服务,该服务必须能够监视文件夹以检测某个文件并读取其中包含的内容。我的代码有一个奇怪的行为,我找不到原因。这是我的相关代码。

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();
                    }
                }

我调试了代码,有时可以正常工作,有时我得到 lineaVent.size() == 0。我对此感到抓狂,我在想,是否有可能事件发生的速度比我的文件的创建速度快?这就是当我尝试将我的 CSV 文件解析为我的 List 对象时 size = 0 的原因?在这种情况下,我没有收到任何 FileNotFoundException。 任何帮助将不胜感激。谢谢。

【问题讨论】:

  • 通过阅读the JavaDocs for FileObserver,我希望对于一个新文件,我会得到一个CREATE 事件、零个或多个MODIFY 事件和一个CLOSE_WRITE 事件。看看你收到了哪些事件,如果你确实看到了CLOSE_WRITE,你可能应该推迟你的工作,直到事件发生之后。
  • 所以问题是事件发生了,我尝试读取文件,它仍然是空的?我必须在其中嵌套另一个 If 用于 CLOSE_WRITE 然后再读取它吗?
  • “所以问题是事件发生了,我尝试读取文件,它仍然是空的?” ——这是我的猜测,是的。 “我必须在其中嵌套另一个 If 用于 CLOSE_WRITE 然后再读取它吗?” -- 我不能真正回答这个问题,因为这是你的应用,不是我的。
  • 我试过了,现在可以了!非常感谢你如果你想把它作为答案。或者我编辑我的问题?

标签: android service fileobserver


【解决方案1】:

我不是 inotify POSIX API 的专家,IIRC 是 FileObserver 的基础。但是,鉴于CREATEMODIFYCLOSE_WRITE 有单独的事件,因此CREATE 事件仅用于文件创建——换句话说,在文件系统中分配新条目是有道理的为文件。这将创建一个空文件,或者可能是一个具有一些初始字节负载的文件,但可能需要其他 MODIFY 调用来写出全部内容。然后将调用CLOSE_WRITE 来指示正在写入文件的人现在已经关闭了他们的文件句柄。

因此,如果您正在监视要创建的某个文件,请将其读入,监视 CREATE,然后在同一文件上监视 CLOSE_WRITE,然后尝试读取它,看看是否有效更好。

【讨论】:

    最近更新 更多