复制的文件已损坏
Files copied are corrupted
我正在尝试传输 Android 中的一些文件。
我有文件列表,然后将它们传输到所需位置。
文件类型可以是任何图像、视频、音频、Gif、PowerPoint、Word 等
文件列表的大小在 100 左右。
这是我用来传输文件的代码
public static boolean copy(File copy, String directory, Context con) {
static FileInputStream inStream = null;
static OutputStream outStream = null;
DocumentFile dir = getDocumentFileIfAllowedToWrite(new File(directory), con);
String mime = "";
DocumentFile copy1 = dir.createFile(mime, copy.getName());
try {
inStream = new FileInputStream(copy);
outStream = con.getContentResolver().openOutputStream(copy1.getUri());
byte[] buffer = new byte[16384];
int bytesRead;
while ((bytesRead = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, bytesRead);
}
}
catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
inStream.close();
outStream.close();
return true;
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
谁能解释一下传输后文件损坏的原因以及可以采取的预防措施。
编辑:这就是我使用函数的方式
String from = "/storage/emulated/0/Pictures/IMG.jpg";
String to = "/storage/3096-13FF/Pictures";
Class.copy(from, to, this);
编辑 2:原始文件大小平均约为 1-2 MB。
复制的文件大小 = 未知,因为此问题已由用户提出。
这是通过输入路径return一个DocumentFile的方法。
public static DocumentFile getDocumentFileIfAllowedToWrite(File file, Context con) {
List<UriPermission> permissionUris = con.getContentResolver().getPersistedUriPermissions();
for (UriPermission permissionUri : permissionUris) {
Uri treeUri = permissionUri.getUri();
DocumentFile rootDocFile = DocumentFile.fromTreeUri(con, treeUri);
String rootDocFilePath = "SD CARD PATH";
if (file.getAbsolutePath().startsWith(rootDocFilePath)) {
ArrayList<String> pathInRootDocParts = new ArrayList<String>();
while (!rootDocFilePath.equals(file.getAbsolutePath())) {
pathInRootDocParts.add(file.getName());
file = file.getParentFile();
}
DocumentFile docFile = null;
if (pathInRootDocParts.size() == 0) {
docFile = DocumentFile.fromTreeUri(con, rootDocFile.getUri());
} else {
for (int i = pathInRootDocParts.size() - 1; i >= 0; i--) {
if (docFile == null) {
docFile = rootDocFile.findFile(pathInRootDocParts.get(i));
} else {
docFile = docFile.findFile(pathInRootDocParts.get(i));
}
}
}
if (docFile != null && docFile.canWrite()) {
return docFile;
} else {
return null;
}
}
}
return null;
}
我让用户使用存储访问框架选择 SD 卡目录,这样我就可以写入 SD 卡中的任何目录。然后,每当必须传输文件时,我都会让用户使用自定义对话框选择路径。
数据在实际写入之前由 OtputStream 缓冲,而不是直接写入文件。在您关闭文件时,一些数据可能仍保留在此缓冲区中。这是提高小型写入性能的优化,它消除了由缓慢的持久性存储设备(如硬盘、SD 卡)引起的大量延迟....
您需要在关闭文件之前刷新输出流缓冲区。我认为所有数据都没有同步到文件。所以在关闭输出之前,尝试刷新缓冲区。
outStream.flush();
并确保数据从文件系统缓存写入存储设备(SD 卡),(如果不是由 close() 隐式完成)
outStream.getFD().sync();
默认情况下,文件系统写入和读取由操作系统缓存。这应该不会影响你,除非你在 copy()
之后的确切时刻取出电池
更多信息已在此处解释
I/O concept flush vs sync
我正在尝试传输 Android 中的一些文件。
我有文件列表,然后将它们传输到所需位置。
文件类型可以是任何图像、视频、音频、Gif、PowerPoint、Word 等
文件列表的大小在 100 左右。
这是我用来传输文件的代码
public static boolean copy(File copy, String directory, Context con) {
static FileInputStream inStream = null;
static OutputStream outStream = null;
DocumentFile dir = getDocumentFileIfAllowedToWrite(new File(directory), con);
String mime = "";
DocumentFile copy1 = dir.createFile(mime, copy.getName());
try {
inStream = new FileInputStream(copy);
outStream = con.getContentResolver().openOutputStream(copy1.getUri());
byte[] buffer = new byte[16384];
int bytesRead;
while ((bytesRead = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, bytesRead);
}
}
catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
inStream.close();
outStream.close();
return true;
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
谁能解释一下传输后文件损坏的原因以及可以采取的预防措施。
编辑:这就是我使用函数的方式
String from = "/storage/emulated/0/Pictures/IMG.jpg";
String to = "/storage/3096-13FF/Pictures";
Class.copy(from, to, this);
编辑 2:原始文件大小平均约为 1-2 MB。 复制的文件大小 = 未知,因为此问题已由用户提出。
这是通过输入路径return一个DocumentFile的方法。
public static DocumentFile getDocumentFileIfAllowedToWrite(File file, Context con) {
List<UriPermission> permissionUris = con.getContentResolver().getPersistedUriPermissions();
for (UriPermission permissionUri : permissionUris) {
Uri treeUri = permissionUri.getUri();
DocumentFile rootDocFile = DocumentFile.fromTreeUri(con, treeUri);
String rootDocFilePath = "SD CARD PATH";
if (file.getAbsolutePath().startsWith(rootDocFilePath)) {
ArrayList<String> pathInRootDocParts = new ArrayList<String>();
while (!rootDocFilePath.equals(file.getAbsolutePath())) {
pathInRootDocParts.add(file.getName());
file = file.getParentFile();
}
DocumentFile docFile = null;
if (pathInRootDocParts.size() == 0) {
docFile = DocumentFile.fromTreeUri(con, rootDocFile.getUri());
} else {
for (int i = pathInRootDocParts.size() - 1; i >= 0; i--) {
if (docFile == null) {
docFile = rootDocFile.findFile(pathInRootDocParts.get(i));
} else {
docFile = docFile.findFile(pathInRootDocParts.get(i));
}
}
}
if (docFile != null && docFile.canWrite()) {
return docFile;
} else {
return null;
}
}
}
return null;
}
我让用户使用存储访问框架选择 SD 卡目录,这样我就可以写入 SD 卡中的任何目录。然后,每当必须传输文件时,我都会让用户使用自定义对话框选择路径。
数据在实际写入之前由 OtputStream 缓冲,而不是直接写入文件。在您关闭文件时,一些数据可能仍保留在此缓冲区中。这是提高小型写入性能的优化,它消除了由缓慢的持久性存储设备(如硬盘、SD 卡)引起的大量延迟....
您需要在关闭文件之前刷新输出流缓冲区。我认为所有数据都没有同步到文件。所以在关闭输出之前,尝试刷新缓冲区。
outStream.flush();
并确保数据从文件系统缓存写入存储设备(SD 卡),(如果不是由 close() 隐式完成)
outStream.getFD().sync();
默认情况下,文件系统写入和读取由操作系统缓存。这应该不会影响你,除非你在 copy()
之后的确切时刻取出电池更多信息已在此处解释
I/O concept flush vs sync