【问题标题】:How to delete file using file observer in Android?如何在 Android 中使用文件观察器删除文件?
【发布时间】:2012-06-07 12:38:21
【问题描述】:

我正在尝试使用文件观察者删除文件。在我的代码中,如果任何文件被推入 SD 卡,它会触发一个创建事件。在那个事件中,我想删除那个文件。我正在尝试下面提供的代码,但我无法删除文件,因为正在复制文件。所以,我现在想在文件成功复制到 SD 卡后删除文件。

文件成功复制到SD卡时是否有任何事件通知?

    public class RecursiveFileObserver extends FileObserver
{
    /** Only modification events */
    public static int CHANGES_ONLY = CREATE | DELETE | CLOSE_WRITE | MOVE_SELF
    | MOVED_FROM | MOVED_TO;

    List<SingleFileObserver> mObservers;
    String mPath;
    int mMask;
    Context mContext;

    public RecursiveFileObserver(String path, Context context)
    {
        this(path, ALL_EVENTS, context);
    }

    public RecursiveFileObserver(String path, int mask, Context context)
    {
        super(path, mask);
        mPath = path;
        mMask = mask;
        mContext = context;
    }

    @Override 
    public void startWatching()
    {
        if (mObservers != null)
            return ;

        mObservers = new ArrayList();
        Stack stack = new Stack();
        stack.push(mPath);

        while (!stack.isEmpty())
        {
            String parent = String.valueOf(stack.pop());
            mObservers.add(new SingleFileObserver(parent, mMask));
            File path = new File(parent);
            File[]files = path.listFiles();
            if (null == files)
            continue;
            for (File f: files)
            {
                if (f.isDirectory() && !f.getName().equals(".") && !f.getName().equals(".."))
                {
                    stack.push(f.getPath());
                }
            }
        }

        for (SingleFileObserver sfo: mObservers)
        {
            sfo.startWatching();
        }
    }

    @Override 
    public void stopWatching()
    {
        if (mObservers == null)
            return ;

        for (SingleFileObserver sfo: mObservers)
        {
            sfo.stopWatching();
        }
        mObservers.clear();
        mObservers = null;
    }

    @Override 
    public void onEvent(int event, String path)
    {
        switch (event)
        {

            case FileObserver.CREATE:
            Log.i("RecursiveFileObserver", "CREATE: " + path);
            File file = new File(path);
            Log.d("File length "," file length = "+file.length());

            if(file.exists()){
            boolean deleted = file.delete(); 
            Log.d("File Deteted "," file Delete = "+deleted);
            }
            break;

        }
    }

    /**
    * Monitor single directory and dispatch all events to its parent, with full path.
    */
    class SingleFileObserver extends FileObserver
    {
        String mPath;

        public SingleFileObserver(String path)
        {
            this(path, ALL_EVENTS);
            mPath = path;
        }

        public SingleFileObserver(String path, int mask)
        {
            super(path, mask);
            mPath = path;
        }

        @Override public void onEvent(int event, String path)
        {
            String newPath = mPath + "/" + path;
            RecursiveFileObserver.this.onEvent(event, newPath);
        }
    }
}


    public class TestFileObserverActivity extends Activity {

    RecursiveFileObserver mObserver;


    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mObserver = new RecursiveFileObserver(Environment.getExternalStorageDirectory().getAbsolutePath(), RecursiveFileObserver.CREATE, this);
        mObserver.startWatching();

        Toast.makeText(getApplicationContext(), "Watching " + Environment.getExternalStorageDirectory().getAbsolutePath(), Toast.LENGTH_LONG).show();

    }
}

请帮助我。提前致谢。

【问题讨论】:

    标签: android file sd-card fileobserver


    【解决方案1】:

    据我所知,无法知道文件何时完成复制。但是有一个我能想到的解决方法。在创建事件中,尝试放置一个每 3 秒检查一次文件完成的 timertask。或者尝试每 3 秒删除一次,直到它不存在,然后将 timertask 从定时器队列中取出。这样它会一直删除复制者所做的,直到文件不再存在。

    希望对您有所帮助。

    【讨论】:

    • 文件观察器所基于的底层 linux inotify 机制可以设置为在打开用于写入的文件关闭时报告“CLOSE_WRITE”事件。不确定文件观察器是否可以做到这一点,或者直接从本机代码使用 inotify 是否有任何障碍。如果文件观察器不支持,这里建议的等待可能更简单。但正如我上面所说,整个项目似乎是个坏主意。
    • 你是对的。 CLOSE_WRITE 完全出乎我的意料。文件观察器是否支持 CLOSE_WRITE;就像使用 CREATE 一样切换它,它会起作用。一方面...设置递归文件观察器需要时间。如果你有一个用户界面,我会在递归文件观察器类中线程开始观察命令,这样它就不会绑定 ui 线程。
    最近更新 更多