Android 同时读取和写入文件

Android 同时读取和写入文件,android,file,concurrency,Android,File,Concurrency,我想同时写入和读取文件而不出错。 例如,我将启动新线程,以便从正在运行的服务写入文件。 在我的活动中,我将启动新线程以读取同一文件。 我不想同时做这件事。像这样的事情: 等待下一个线程的执行,直到上一个线程完成 在前一个线程停止之前,下一个线程不得启动,无论时间消耗如何 我的读写代码: public static final String ROUTE_FILE_NAME = "route.txt"; public static void savePointToFile(Context

我想同时写入和读取文件而不出错。 例如,我将启动新线程,以便从正在运行的服务写入文件。 在我的活动中,我将启动新线程以读取同一文件。 我不想同时做这件事。像这样的事情:

  • 等待下一个线程的执行,直到上一个线程完成
  • 在前一个线程停止之前,下一个线程不得启动,无论时间消耗如何
  • 我的读写代码:

    public static final String ROUTE_FILE_NAME = "route.txt";
    
        public static void savePointToFile(Context context, String point) throws IOException {
    
            FileOutputStream fOut = context.openFileOutput(ROUTE_FILE_NAME, Context.MODE_APPEND);
    
            OutputStreamWriter osw = new OutputStreamWriter(fOut);
            osw.write(point);
            osw.flush();
            osw.close();
        }
    
        public static String readRouteFromFile(Context context) {
            StringBuffer fileContent = new StringBuffer(UIUtils.emptyString());
            byte[] buffer = new byte[1024];
            try {
                FileInputStream fis = context.openFileInput(ROUTE_FILE_NAME);
    
                int length;
    
                while ((length = fis.read(buffer)) != -1) {
                    fileContent.append(new String(buffer));
                }
    
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return fileContent.toString();
        }
    

    提前感谢。

    您可以查看一个特殊的线程池执行器服务

    final ExecutorService threadpool = Executors.newSingleThreadExecutor();
    
    这相当简单,只需创建Runnable并将其放入线程池。它包含一个线程,因此所有可运行程序都按顺序排队。否则,您可以创建一个普通executorservice并将线程池设置为1。实际上是一样的。希望这有帮助

    就这样

    WorkerThread.get(context).read() 
    WorkerThread.get(context).write() 
    
    您甚至可以实现未来的调用,而不是定义显式回调

    只是它如何工作的一般概念。您需要保存文件指针,以便知道在哪里暂停并继续读/写。另外,您将始终从文件中的第一个数据位置开始

    class WorkerThread {
    
        interface Callback {
            void onCompleteRead(String buffer, int pauseReadPointer);
            void onCompleteWrite(int pauseWritePointer);
        }
    
        enum Action {
            READ,
            WRITE
        }
    
        private static WorkerThread singleton;
    
        public static synchronized WorkerThread get(final Context context) {
            if (instance == null) {
                instance = new WorkerThread(context);
            }
            return instance;    
        }    
    
    
    
        private final Context context;
    
        private final ExecutorService threadPool;
    
        private WorkerThread(context) {
            threadPool = Executors.newSingleThreadExecutor()
        }
    
        // PUBLIC READ CALL
        public void read(int resumeReadPointer, Callback callback, "other params") {
            queueJob(READ, null, resumeReadPointer, callback);
        }
    
        // PUBLIC WRITE CALL
        public void write(String in, int resumeWritePointer, Callback callback, "other params") {
            queueJob(WRITE, in, resumeWritePointer, callback);
        }
    
        private void queueJob(final Action action, String buffer, final int pointer, final Callback callback) {
    
            /* Create handler in UI thread. */
            final Handler handler = new Handler() {
                @Override
                public void handleMessage(Message msg) {
    
                    ResultPack pack = (ResultPack) msg.obj;
                    if (Action.READ == action) {
                        callback.onCompleteRead(pack.result, pack.pointer);
                    } else {
                        callback.onCompleteWrite(pack.pointer);
                    }
                }
            };
    
            // single threadpool. everything is FIFO
            threadPool.submit(new FileRunnable(action, buffer, handler, pointer));
        }
    
        private class ResultPack {
            private final String result;
            private final int pointer;
            private ResultPack(String s, int p) {
                this.result = s;
                this.pointer = p;
            }
        }
    
        private class FileRunnable implements Runnable {
    
            private int pointer = 0;
            private final Handler handler;
            private final buffer = buffer;
    
            FileRunnable(final Action action, String buffer, final Handler handler, final int pointer) {
                this.pointer = pointer;
                this.handler = handler;
                this.buffer = buffer;
            }
    
            @Override
            public void run() {
    
                if (Action.READ == action) {
                    ResultPack pack = readRouteFromFile(..., pointer);
                } else { // write
                    ResultPack pack = savePointToFile(..., buffer, pointer);
                }
    
                Message message = Message.obtain();
                message.obj = pack;
                handler.sendMessage(message);
            }
        }
    }
    

    如果只想让从一个线程调用的read方法等待从另一个线程调用的write方法完成,反之亦然,只需在一个公共对象上同步这两个方法:

    private static final Object fileLock = new Object();
    
    public static String readFile() {
        synchronize(fileLock) {
            [your current read code here]
        } 
    }
    
    public static void write(String data) {
        synchronize(fileLock) {
            [your current write code here]
        } 
    }
    

    提前感谢什么?因为任何人都可以帮助我!我可以将
    锁定对象
    与静态方法一起使用吗?可以,您可以创建一个静态锁定对象,相关的静态方法在该对象上同步。我在我的应用程序中这样做。你能提供一个例子吗?我在回答中更新了代码,向你展示了如何做。谢谢你,我会再试一次的