复制后文件丢失 - Android

时间:2014-03-11 08:07:10

标签: android file android-sdcard android-file

我正在通过从一个文件夹到另一个文件夹的线程移动文件(大约100-2000个文件,每个大小100-200KB)。一切顺利,但在一些三星&带有 sdcard 的LG设备,在复制后突然发现全部或部分设备丢失。

每次都不会发生这种情况,但大约每20次发生一次。

到目前为止,我尝试了3种技术:

public void copyMethodA(File src, File dst){
    if(!dst.exists()){
        src.renameTo(dst);
    }
}

copyMethodA();在大多数情况下导致文件丢失。

public void copyMethodB(File sourceFile, File destFile) throws IOException {

    if (!destFile.exists()) {
        destFile.createNewFile();
    }

    try {
        FileChannel source = new FileInputStream(sourceFile).getChannel();
        FileChannel destination = new FileOutputStream(destFile).getChannel();
        destination.transferFrom(source, 0, source.size());
    } finally {
        source.close();
        destination.close();
    }
}

copyMethodB();导致文件丢失的次数比A少。

public void copyMethodC(File src, File dst) throws IOException {
    InputStream in = new FileInputStream(src);
    OutputStream out = new FileOutputStream(dst);

    byte[] buf = new byte[10240];
    int len;
    while ((len = in.read(buf)) > 0) {
        out.write(buf, 0, len);
    }
    in.close();
    out.close();
}

copyMethodC();很少导致文件丢失。 因此目前使用此

所有3种方法都能很好地工作,而Xperia C& C Nexus 5(均使用内部存储) 但在LG Optimus One(使用SD卡)和一些三星设备(使用内部或SD卡)上观察到文件丢失

有关我测试过的设备的信息:

  • Nexus 5 - Android 4.4.2
  • Xperia C - Android 4.2.2
  • LG Optimus One - Android 2.3.3
  • 三星设备 - Android 4.0及以上版本

(我猜这个问题与使用的Android版本无关)

我正在避免使用庞大的第三方文件IO API,因为我的Android应用程序的大小只有300KB。使用像Apache commons.io这样的API会使它膨胀到大约2.5MB

还有其他安全,安全和更好的复制文件的方法?

感谢。

2 个答案:

答案 0 :(得分:1)

我认为你应该这样:

  • 您应该检查renameTo的返回值,因为javadoc表示它的失败原因很多。

  • 如果renameTo调用失败,请使用第三种方法,使用try / catch块在读取/写入流时捕获IOException,并确保在复制成功时仅删除源文件。然后,您可以检查异常以了解副本失败的原因,并可能稍后重试。

我正在这样做(使用1024字节的缓冲区,比如@beni的答案)来复制几百个文件,我从未见过任何损失。

答案 1 :(得分:0)

我正在使用此功能并始终有效。我在Nexus 5上测试了这段代码.in.read(buf)方法在文件末尾返回-1,在其他情况下返回readed的字节数。所以,试试吧。

public static void copyFile(InputStream in, OutputStream out) throws IOException {
    byte[] buffer = new byte[1024];
    int read;
    while ((read = in.read(buffer)) != -1) {
        out.write(buffer, 0, read);
    }
}
相关问题