互联网上有一个非常流行的类RecursiveFileObserver,可用于检测文件系统上进行的任何读/写更改,以递归方式可以在hereherehere中找到该类。 >。但是问题是如何使用此校准?我将其复制到我的项目中,但它没有任何作用。我该如何开始呢?
我是初学者。

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

最佳答案

我对RecursiveFileObserver进行了一些更改:


添加成员变量activityactivity传递给构造函数。然后在创建或修改文件时将其用于输出Toast消息。
onEvent()切换的情况下,只要创建新文件或修改现有文件,就会显示Toast消息。


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

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

注意第一行是package com.example.shuwnyuan.barchart;。您必须将其替换为您自己的程序包名称,然后从MainActivity.java文件的第一行获取您的程序包名称。

// 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中的文件更改。为此,我们需要明确要求用户授予文件读/写权限。我们在onCreateMainActivity中执行此操作。授予权限后,我们将监视文件更改的路径。然后,我们写入名为“ MyTestFile”的文件以测试RecursiveFileObserver。首次写入时,将创建新文件。之后,如果已经存在,则修改相同的文件。创建或修改文件时将显示Toast消息。

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

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

10-07 19:18
查看更多