【发布时间】:2015-01-01 19:25:03
【问题描述】:
我正在设计一个应用程序,它的主线程通过读取和写入来与 .txt 文件交互。
这个应用还有一个后台 IntentService 可以读写这个文件。
我需要能够读入一个文件,并用新数据将其写回,同时确保另一个线程在这两个步骤之间没有更改文件的数据。
我认为 FileLock 是我想要的,但是当我开始读取文件时,我无法锁定文件,因为 InputFileStream.getChannel().lock() 给出了异常。 (NonWritableChannelException)。
我希望代码类似于:
File theFile = new File(file.txt);
FileInputStream in = new FileInputStream(theFile);
//should block here if it can't immediately lock
FileLock fileLock = in.getChannel().lock();
String inString = "";
int content;
while((content = in.read()) != -1){
inString += Character.toString(((char) content));
}
in.close();
inString += "new data";
out = new FileOutputStream(file);
out.write(finalString.getBytes());
out.flush();
out.close();
//releases the lock
fileLock.release();
我意识到可能可行的一个场景是使用 RandomAccessFile。因为在读取这些内容时,您可以声明它们“rw”权限(读写),因此您可以使用 .getChannel().lock() 但我想在深入研究之前先询问社区。p>
【问题讨论】:
-
“我正在设计一个应用程序,它的主线程通过读取和写入来与 .txt 文件进行交互。这个应用程序还有一个后台 IntentService 可以读取和写入这个文件。” - 为什么?为什么不使用一个具有工作队列的实体来负责写入和读取或返回缓存数据?另外,我希望当您提到“主线程”执行读取时,您并不意味着您正在主应用程序线程上执行磁盘 I/O,因为这会导致卡顿。
-
这些是小文件(几百个字符)。为什么有后台线程访问文件?因为它是一个使用 AlarmManager 在预定时间在手机后台执行操作的应用程序。它需要做互联网下载,不能在A广播接收器类中运行,因此广播接收器类必须运行一个意图服务,其目的是在线检查文件。如果某个条件发生了,则需要写入用户界面读取的文件,以便将信息显示给用户。
-
这篇文章的名字很糟糕。一个更好的标题应该是:如何在确保没有其他线程可以修改文件的同时修改文件?
-
“如果发生某种情况,它需要写入用户界面读取的文件,以便向用户显示信息” - 这就是我的建议可能是重新设计。特别是对于小文件,请使用由文件支持的内存缓存。您的服务会更新文件并使用进程内事件总线让 UI 层知道(如果当前存在)数据已更改。唯一需要读取文件的时间是重新启动进程时,如果您在执行写入的同一
IntentService中执行此操作,则 I/O 会自动序列化。 -
你是对的!好的,所以我有这个文件来跟踪正在运行的警报管理器,并且这个文件还有线程将写入它的“更新”数据。创建新的 AlarmManager 时,UI 必须更改此文件。相反,我会将这些变化的数据移动到一个单独的文件中,该接口将只读取,而不再需要写入。
标签: android file synchronization locking