Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/226.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 试图覆盖文件会导致空白文件_Java_Android_File - Fatal编程技术网

Java 试图覆盖文件会导致空白文件

Java 试图覆盖文件会导致空白文件,java,android,file,Java,Android,File,在我目前正在开发的应用程序中,部分功能是将设备上保存的数据写入通过USB-OTG适配器连接的闪存驱动器。具体来说,该设备是一个运行4.2.2的根摩托罗拉Xoom。我可以成功地将文件写入驱动器并在计算机上读取它们。那部分很好用。但是,当我尝试用新信息替换现有文件时,生成的文件将显示为空。我甚至在写入新数据之前删除了现有文件。奇怪的是,将内部文件的内容复制到闪存驱动器后,我会记录生成文件的长度。它始终与输入文件匹配,并且始终为非0数字,但该文件在我的计算机上仍显示为空白。有人能帮忙解决这个问题吗?下

在我目前正在开发的应用程序中,部分功能是将设备上保存的数据写入通过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开发者,所以我真的不知道。谢谢你的推荐,我会看看