同时读写文件

时间:2015-07-07 20:14:54

标签: android file concurrency

我想在没有错误的情况下同时从文件中写入和读取。 例如,我将启动新的Thread以从我正在运行的服务写入文件。 在我的活动中,我将从同一个文件开始新的Thread读取。 我不想同步这样做。有点像这样:

  1. 等待执行下一个线程,直到上一个完成。
  2. 下一个线程必须在前一个线程停止之前才能启动,无论时间消耗如何。
  3. 我的读写代码:

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

    提前致谢。

2 个答案:

答案 0 :(得分:2)

您可以查看特殊的线程池执行程序服务。

final ExecutorService threadpool = Executors.newSingleThreadExecutor();

它相当简单,只需创建runnables并将其放入线程池中。它包含一个线程,因此所有runnable都按顺序排队。否则,您可以创建一个正常的executorservice并将线程池设置为1.实际上它是相同的。希望这有帮助

http://www.concretepage.com/java/newsinglethreadexecutor_java

所以它就像

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

答案 1 :(得分:2)

如果您只是希望从线程调用的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]
    } 
}