Java 试图覆盖文件会导致空白文件
在我目前正在开发的应用程序中,部分功能是将设备上保存的数据写入通过USB-OTG适配器连接的闪存驱动器。具体来说,该设备是一个运行4.2.2的根摩托罗拉Xoom。我可以成功地将文件写入驱动器并在计算机上读取它们。那部分很好用。但是,当我尝试用新信息替换现有文件时,生成的文件将显示为空。我甚至在写入新数据之前删除了现有文件。奇怪的是,将内部文件的内容复制到闪存驱动器后,我会记录生成文件的长度。它始终与输入文件匹配,并且始终为非0数字,但该文件在我的计算机上仍显示为空白。有人能帮忙解决这个问题吗?下面是我做这项工作的Java 试图覆盖文件会导致空白文件,java,android,file,Java,Android,File,在我目前正在开发的应用程序中,部分功能是将设备上保存的数据写入通过USB-OTG适配器连接的闪存驱动器。具体来说,该设备是一个运行4.2.2的根摩托罗拉Xoom。我可以成功地将文件写入驱动器并在计算机上读取它们。那部分很好用。但是,当我尝试用新信息替换现有文件时,生成的文件将显示为空。我甚至在写入新数据之前删除了现有文件。奇怪的是,将内部文件的内容复制到闪存驱动器后,我会记录生成文件的长度。它始终与输入文件匹配,并且始终为非0数字,但该文件在我的计算机上仍显示为空白。有人能帮忙解决这个问题吗?下
AsyncTask
中的相关代码
@Override
protected Void doInBackground(Void... params) {
File[] files = context.getFilesDir().listFiles();
for (File file : files) {
if (file.isFile()) {
List<String> nameSegments = Arrays.asList(file.getName().split(
"_"));
Log.d("source file", "size: " + file.length());
String destinationPath = "/storage/usbdisk0/"
+ nameSegments.get(0) + "/" + nameSegments.get(1) + "/";
File destinationPathFile = new File(destinationPath);
if (!destinationPathFile.mkdirs()) {
destinationPathFile.mkdirs();
}
File destinationFile = new File(destinationPathFile,
nameSegments.get(2));
FileReader fr = null;
FileWriter fw = null;
try {
fr = new FileReader(file);
fw = new FileWriter(destinationFile, false);
int c = fr.read();
while (c != -1) {
fw.write(c);
c = fr.read();
}
fw.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fr.close();
fw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Log.d("destination file", "size: " + new File(destinationFile.getPath()).length());
}
}
return null;
}
@覆盖
受保护的Void doInBackground(Void…参数){
File[]files=context.getFilesDir().listFiles();
用于(文件:文件){
if(file.isFile()){
List nameSegments=Arrays.asList(file.getName().split(
"_"));
Log.d(“源文件”,“大小:”+file.length());
字符串destinationPath=“/storage/usbdisk0/”
+nameSegments.get(0)+“/”+nameSegments.get(1)+“/”;
File destinationPath File=新文件(destinationPath);
如果(!destinationPathFile.mkdirs()){
destinationPathFile.mkdirs();
}
File destinationFile=新文件(destinationPathFile,
获取(2));
FileReader fr=null;
FileWriter fw=null;
试一试{
fr=新文件读取器(文件);
fw=新文件编写器(destinationFile,false);
int c=fr.read();
而(c!=-1){
fw.写入(c);
c=fr.read();
}
fw.flush();
}捕获(IOE异常){
e、 printStackTrace();
}最后{
试一试{
fr.close();
fw.close();
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
Log.d(“目标文件”,“大小:”+新文件(destinationFile.getPath()).length());
}
}
返回null;
}
编辑:
根据@Simon的建议,我在代码中添加了output.flush()
。这不会改变结果
编辑#2:
我用这个做了一些进一步的测试,发现了一些有趣的东西。如果我在写入闪存驱动器后,但在将其从OTG适配器中卸下之前,转到设置->存储->卸载USB存储,则一切都会正常工作。但是,写入后未能弹出驱动器会导致数据未被写入。奇怪的是,文件夹结构和文件本身都是在驱动器上创建的,但文件总是空的。还有一件事:如果我在移除驱动器之前打开文件管理器应用程序并打开该文件,那么这些文件都会像它们应该存在的那样存在。然而,即使移除设备,将其直接插回平板电脑并打开任何文件,也会导致文件看起来是空的。我无法理解这一切,这令人难以置信地沮丧。有人能帮忙吗
编辑#3:
我还改为使用
FileReader
s和FileWriter
s,以了解会发生什么。在这一点上,我并不关心效率,我只是希望文件编写能够可靠地工作。这一变化并未影响该问题。更新的代码张贴在上面。听起来文件系统正在缓存您的更改,但在您弹出更改之前,不会将更改写入闪存驱动器。我认为没有办法刷新文件系统缓存,所以最好的解决方案似乎只是卸载然后重新安装闪存驱动器 在调用FileReader.read()之前,尝试使用FileReader.ready()
方法,
并确保您的
文件读取器中是否确实有一些字节。试试这个,使用缓冲读取器进行写入
try
{
fw = new FileWriter(destinationFile);
BufferedWriter writer=new BufferedWriter(fw);
writer.append(yourText); // Append can be changed to write or something if you want to overwrite
writer.close();
}
catch (Exception e) {
throw new RuntimeException(e);
}
finally {
if (fw != null) {
try {
fw.flush();
fw.close();
}
catch (IOException e) {
}
我找到了解决我问题的办法。Android系统似乎会缓冲SD卡/闪存驱动器上的一些文件,然后在弹出时将它们写入闪存驱动器。“我的文件”操作后的以下代码将缓冲区与文件系统同步,并允许立即从设备中删除闪存驱动器,而不会丢失数据。值得注意的是,这确实需要根访问;它无法在非根设备上工作
try {
Process p = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(p.getOutputStream());
os.writeBytes("sync; sync\n");
os.writeBytes("exit\n");
os.flush();
} catch (Exception e) {
e.printStackTrace();
}
我的解决方案的来源:在关闭输出流之前,您在哪里flush()
输出流?它作为Java应用程序运行良好,可能与文件系统有关?这实际上是非常可能的。我只是添加了一些代码,在闪存驱动器的根目录中创建一个空白文件,然后将其删除delete()
返回true,但文件仍然存在。这可能是问题的一部分。打印文件长度的log语句是错误的。您总是打印文件路径的长度,而不是打印文件内容的长度。尝试使用File.length()方法,查看内容是否为0。希望此帮助可以指定错误的确切位置?据我所知,我总是对文件对象调用length();事实上,出于安全考虑,这在Android中是不可能通过编程实现的。然而我希望你的解释是正确的,这就是我现在开始思考的。问题仍然存在,为什么它会这样,我如何才能摆脱它?我的坏,我想它是这样。如果有很多人问同样的问题,这可能会有所帮助。有些东西可能会有帮助。我不是android开发者,所以我真的不知道。谢谢你的推荐,我会看看