首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用FileObserver?

如何使用FileObserver?
EN

Stack Overflow用户
提问于 2018-02-07 23:35:38
回答 1查看 2.1K关注 0票数 0

internet上有一个非常流行的类RecursiveFileObserver,它可以用于检测文件系统上的任何读/写更改,递归地,可以找到这里这里这里。但问题是我该如何使用这些火山灰呢?我把它复制到我的项目中,它什么也不做。我该怎么开始呢?我是个初学者。

代码语言:javascript
复制
package com.toraleap.collimator.util;
//from   w  w w .j  a  v  a  2s.c  o  m
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

import android.os.FileObserver;
import android.util.Log;

/**
 * Enhanced FileObserver to support recursive directory monitoring basically.
 * @author    uestc.Mobius <mobius@toraleap.com>
 * @version  2011.0121
 */
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;

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

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

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

        mObservers = new ArrayList<SingleFileObserver>();
        Stack<String> stack = new Stack<String>();
        stack.push(mPath);

        while (!stack.isEmpty()) {
            String parent = 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.ACCESS:
                Log.i("RecursiveFileObserver", "ACCESS: " + path);
                break;
            case FileObserver.ATTRIB:
                Log.i("RecursiveFileObserver", "ATTRIB: " + path);
                break;
            case FileObserver.CLOSE_NOWRITE:
                Log.i("RecursiveFileObserver", "CLOSE_NOWRITE: " + path);
                break;
            case FileObserver.CLOSE_WRITE:
                Log.i("RecursiveFileObserver", "CLOSE_WRITE: " + path);
                break;
            case FileObserver.CREATE:
                Log.i("RecursiveFileObserver", "CREATE: " + path);
                break;
            case FileObserver.DELETE:
                Log.i("RecursiveFileObserver", "DELETE: " + path);
                break;
            case FileObserver.DELETE_SELF:
                Log.i("RecursiveFileObserver", "DELETE_SELF: " + path);
                break;
            case FileObserver.MODIFY:
                Log.i("RecursiveFileObserver", "MODIFY: " + path);
                break;
            case FileObserver.MOVE_SELF:
                Log.i("RecursiveFileObserver", "MOVE_SELF: " + path);
                break;
            case FileObserver.MOVED_FROM:
                Log.i("RecursiveFileObserver", "MOVED_FROM: " + path);
                break;
            case FileObserver.MOVED_TO:
                Log.i("RecursiveFileObserver", "MOVED_TO: " + path);
                break;
            case FileObserver.OPEN:
                Log.i("RecursiveFileObserver", "OPEN: " + path);
                break;
            default:
                Log.i("RecursiveFileObserver", "DEFAULT(" + event + "): " + path);
                break;
        }
    }

    /**
     * Monitor single directory and dispatch all events to its parent, with full path.
     * @author    uestc.Mobius <mobius@toraleap.com>
     * @version  2011.0121
     */
    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);
        }
    }
}
EN

回答 1

Stack Overflow用户

发布于 2018-02-08 04:03:32

我对RecursiveFileObserver做了很少的修改

  • 添加成员变量activityactivity被传递给构造函数。然后,它用于在创建或修改文件时输出Toast消息。
  • onEvent()交换机的情况下,每当创建新文件或修改现有文件时,都会显示Toast消息。

您可以按照以下步骤设置文件观察者:

1)如果您已经在Android中有一个项目,那么在与您的MainActivity.java文件相同的文件夹/目录中添加一个新的java文件。将新类命名为RecursiveFileObserver。将以下内容复制并粘贴到RecursiveFileObserver.java文件中。

注意,第一行是package com.example.shuwnyuan.barchart;--您必须用自己的包名替换它,从MainActivity.java文件的第一行获取包名。

代码语言:javascript
复制
// replace this below 1 line with your own package name.
package com.example.shuwnyuan.barchart;

//from   w  w w .j  a  v  a  2s.c  o  m
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

import android.app.Activity;
import android.os.FileObserver;
import android.util.Log;
import android.widget.Toast;

/**
 * Enhanced FileObserver to support recursive directory monitoring basically.
 * @author    uestc.Mobius <mobius@toraleap.com>
 * @version  2011.0121
 */
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;
    Activity activity;

    public RecursiveFileObserver(String path, Activity activity) {
        super(path, ALL_EVENTS);
        mPath = path;
        mMask = ALL_EVENTS;

        this.activity = activity;
    }

    public RecursiveFileObserver(String path, int mask, Activity activity) {
        super(path, mask);
        mPath = path;
        mMask = mask;

        this.activity = activity;
    }

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

        mObservers = new ArrayList<SingleFileObserver>();
        Stack<String> stack = new Stack<String>();
        stack.push(mPath);

        while (!stack.isEmpty()) {
            String parent = 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, final String path) {
        switch (event)
        {
            case FileObserver.ACCESS:
                Log.i("RecursiveFileObserver", "ACCESS: " + path);
                break;
            case FileObserver.ATTRIB:
                Log.i("RecursiveFileObserver", "ATTRIB: " + path);
                break;
            case FileObserver.CLOSE_NOWRITE:
                Log.i("RecursiveFileObserver", "CLOSE_NOWRITE: " + path);
                break;
            case FileObserver.CLOSE_WRITE:
                Log.i("RecursiveFileObserver", "CLOSE_WRITE: " + path);
                break;
            case FileObserver.CREATE:
                Log.i("RecursiveFileObserver", "CREATE: " + path);

                // show Toast message
                activity.runOnUiThread(new Runnable() {
                    public void run() {
                        Toast.makeText(activity, "File created: " + path, Toast.LENGTH_LONG).show();
                    }
                });

                break;
            case FileObserver.DELETE:
                Log.i("RecursiveFileObserver", "DELETE: " + path);
                break;
            case FileObserver.DELETE_SELF:
                Log.i("RecursiveFileObserver", "DELETE_SELF: " + path);
                break;
            case FileObserver.MODIFY:
                Log.i("RecursiveFileObserver", "MODIFY: " + path);

                // show Toast message
                activity.runOnUiThread(new Runnable() {
                    public void run() {
                        Toast.makeText(activity, "File modified: " + path, Toast.LENGTH_LONG).show();
                    }
                });

                break;
            case FileObserver.MOVE_SELF:
                Log.i("RecursiveFileObserver", "MOVE_SELF: " + path);
                break;
            case FileObserver.MOVED_FROM:
                Log.i("RecursiveFileObserver", "MOVED_FROM: " + path);
                break;
            case FileObserver.MOVED_TO:
                Log.i("RecursiveFileObserver", "MOVED_TO: " + path);
                break;
            case FileObserver.OPEN:
                Log.i("RecursiveFileObserver", "OPEN: " + path);
                break;
            default:
                Log.i("RecursiveFileObserver", "DEFAULT(" + event + "): " + path);
                break;
        }
    }

    /**
     * Monitor single directory and dispatch all events to its parent, with full path.
     * @author    uestc.Mobius <mobius@toraleap.com>
     * @version  2011.0121
     */
    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);
        }
    }
}

2)我们将关注Android ExternalStorageDirectory中的文件更改。为此,我们需要显式地要求用户授予文件读/写权限。我们在onCreate of MainActivity中这样做。授予权限后,我们监视路径中的文件更改。然后,我们写入一个名为"MyTestFile“的文件来测试RecursiveFileObserver。在第一次编写时,将创建新文件。在此之后,如果已存在相同的文件,则对其进行修改。创建或修改文件时将显示Toast消息。

在您的MainActivity类中,进行了以下更改:

代码语言:javascript
复制
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        .....

        if (Settings.System.canWrite(this) == false) {
            // for first time, request user to grant file permission
            requestPermissions(new String[] {
                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    Manifest.permission.READ_EXTERNAL_STORAGE
                }, 3000
            );

        } else {
            // permission is already granted
            // start watching path & write to file for test
            watchPathAndWriteFile();
        }
    }

    .....
    ......

    // This function does 2 things:
    // 1) watch path for files changes using "RecursiveFileObserver"
    // 2) write to a file for testing
    public void watchPathAndWriteFile() {
        // the following path depends on your Android device. On my system, it is: "/storage/emulated/0/"
        String path = Environment.getExternalStorageDirectory().getPath() + "/";
        RecursiveFileObserver observer = new RecursiveFileObserver(path, this);

        // start watching the path
        observer.startWatching();

        // if file "MyTestFile" not exist, new file is created. Else file is modified
        try {
            FileWriter out = new FileWriter(new File(Environment.getExternalStorageDirectory() + "MyTestFile"));
            out.write("my file content for test...");
            out.close();
        } catch (IOException e) {
            android.util.Log.e("writeStringAsFile", "Exception: " + e);
        }
    }

    // in "onCreate", user is prompted to grant file read / write permission
    // this function is invoked automatically after user allowed / denied permission
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case 3000: {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // user granted permission
                    // start watching for path & write to file for testing.
                    watchPathAndWriteFile();
                } else {
                    // user denied permission
                    android.util.Log.e("Permission", "Denied");
                }

                return;
            }
        }
    }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48675119

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档