android:删除相同后复制.jpg图像会出错

问题描述 投票:0回答:1

从应用程序Java端,使用file.mkdir创建目录,并使用Java API从USB大容量存储设备复制文件夹(jpg_3)中存在的JPG文件。

然后使用File.delete()方法从内部存储器中删除相同的文件和目录。

当试图将这些相同的文件添加到内部存储器时,文件没有被复制,而是得到以下异常:

02-20 16:11:56.727 17471 17964 E XXXXXX:java.io.FileNotFoundException:/storage/emulated/0/XXX/jpg_3/galaxy-wallpaper-4.jpg:open failed:ENOENT(没有这样的文件或目录)

后来我们发现下面提到的进程仍在访问那些已删除的文件。

shell @ ABC:/ storage / emulated / legacy / XXX #lsof | grep jpg_3

sdcard 1819 media_rw 5 ??? ??? ??? ??? /data/media/0/XXX/jpg_3/galaxy-wallpaper-4.jpg(已删除)

android.p 3205 u0_a4 67 ??? ??? ??? ??? /storage/emulated/0/XXX/jpg_3/galaxy-wallpaper-4.jpg(已删除)

shell @ ABC:/ storage / emulated / legacy / XXX#ps 3205

USER PID PPID VSIZE RSS WCHAN PC NAME

u0_a4 3168 1830 1022984 58080 ffffffff 76e7f868 S android.process.media

如果我们尝试使用mkdir创建具有相同名称的目录(在ADB Shell中),我们得到以下错误:

shell @ ABC:/ storage / emulated / legacy / XXX#mkdir jpg_3 mkdir jpg_3失败,设备或资源忙

我们怀疑这些.jpg文件的软链接即使在删除后仍然存在,这会导致上述错误。

我们尝试了File.delete()以及下面提到的代码参考:android : deleting an image

public static void deleteFileFromMediaStore(final ContentResolver contentResolver, final File file) {
String canonicalPath;
try {
    canonicalPath = file.getCanonicalPath();
} catch (IOException e) {
    canonicalPath = file.getAbsolutePath();
}
final Uri uri = MediaStore.Files.getContentUri("external");
final int result = contentResolver.delete(uri,
        MediaStore.Files.FileColumns.DATA + "=?", new String[]{canonicalPath});
if (result == 0) {
    final String absolutePath = file.getAbsolutePath();
    if (!absolutePath.equals(canonicalPath)) {
        contentResolver.delete(uri,
                MediaStore.Files.FileColumns.DATA + "=?", new String[]{absolutePath});
    }
}

}

如何解决.jpg文件的softlink问题?

N.B:我们还尝试重新扫描设备

MediaScannerConnection.scanFile(mService.getApplicationContext(), new String[]{
            oDeleteFile.getAbsolutePath().toString()
    }, null, null);

但它没有帮助。

提前致谢

android jpeg delete-file file-copying
1个回答
0
投票

在Android Nougat版本中,有一个文件ExifInterface.java(/ frameworks / base / media / java / android / media /),它有一个函数'getJpegAttributes',它从JPEG输入流中加载EXIF属性。下面是该文件的链接 - http://androidxref.com/7.0.0_r1/xref/frameworks/base/media/java/android/media/ExifInterface.java

在此函数中,DataInputStream已由以下代码创建 -

DataInputStream dataInputStream = new DataInputStream(inputStream);

但是,在函数结束时,尚未关闭相同的文件流。因此,即使MediaScannerService.java完成了对复制文件的扫描,Android Media Provider进程也无需访问该文件。因此,当我们在函数结束时通过以下代码关闭文件流时 -

if (null != dataInputStream) {
    Log.d(TAG, "dataInputStream.close()" );
    dataInputStream.close();
}

问题得到解决。

© www.soinside.com 2019 - 2024. All rights reserved.