Java 复制的文件已损坏
我正在尝试用Android传输一些文件 我拥有文件列表,然后将它们传输到所需的位置 文件类型可以是任何图像、视频、音频、GIF、PowerPoint、Word等 文件列表的大小约为100 这是我用来传输文件的代码Java 复制的文件已损坏,java,android,file,corruption,Java,Android,File,Corruption,我正在尝试用Android传输一些文件 我拥有文件列表,然后将它们传输到所需的位置 文件类型可以是任何图像、视频、音频、GIF、PowerPoint、Word等 文件列表的大小约为100 这是我用来传输文件的代码 public static boolean copy(File copy, String directory, Context con) { static FileInputStream inStream = null; static OutputStream outStr
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-2MB。
复制的文件大小=未知,因为此问题已由用户提出
这是通过输入路径返回文档文件的方法
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;
}
publicstaticdocumentfile getDocumentFileIfAllowedToWrite(文件文件,上下文con){
List permissionUris=con.getContentResolver().getPersistedUrmissions();
for(UriPermission permissionUri:permissionUri){
Uri treeUri=permissionUri.getUri();
DocumentFile rootDocFile=DocumentFile.fromTreeUri(con,treeUri);
字符串rootDocFilePath=“SD卡路径”;
if(file.getAbsolutePath().startsWith(rootDocFilePath)){
ArrayList pathInRootDocParts=新的ArrayList();
而(!rootDocFilePath.equals(file.getAbsolutePath())){
pathInRootDocParts.add(file.getName());
file=file.getParentFile();
}
DocumentFile docFile=null;
if(pathInRootDocParts.size()==0){
docFile=DocumentFile.fromtreeeuri(con,rootDocFile.getUri());
}否则{
对于(int i=pathInRootDocParts.size()-1;i>=0;i--){
if(docFile==null){
docFile=rootDocFile.findFile(pathInRootDocParts.get(i));
}否则{
docFile=docFile.findFile(pathInRootDocParts.get(i));
}
}
}
if(docFile!=null&&docFile.canWrite()){
返回文档文件;
}否则{
返回null;
}
}
}
返回null;
}
我让用户使用存储访问框架选择SD卡目录,以便我可以写入SD卡中的任何目录。然后,当需要传输文件时,我会让用户使用自定义对话框选择路径。数据在实际写入之前由OtputStream缓冲,而不是直接写入文件。在关闭文件时,某些数据可能仍保留在此缓冲区中。这是一种提高小型写入性能的优化,它消除了硬盘、SD卡等慢速持久存储设备造成的大量延迟 在关闭文件之前,需要刷新输出流缓冲区。我认为所有数据都没有同步到文件。所以在关闭输出之前,请尝试刷新缓冲区 冲水 并确保数据从文件系统缓存写入存储设备(SD卡)(如果不是通过close()隐式完成) outStream.getFD().sync() 默认情况下,文件系统写入和读取由操作系统缓存。这不会影响您,除非您在复制()后的确切时刻取下电池 这里已经解释了更多
为什么不使用
文件。复制(源、目标、替换现有)代码>?@sarkasronie不使用此方法的原因是应用程序可能不仅将数据传输到同一存储器,还将数据传输到可移动SD卡。从Android 5.0及以上版本开始,必须使用存储访问框架将数据传输到可移动存储。public static boolean copy(文件副本,字符串目录,
请从一个调用此函数的示例开始。我们想查看所有完整路径。请将示例放在您的帖子中。@greenapps抱歉。我已经添加了信息。请您看一看。Android不太常用,但mime=“application/octet stream”;
(二进制数据)我本以为会的。谢谢你的回答。但是这个问题的代码几乎与原始海报上发布的代码相同,很少复制损坏的文件。有什么原因吗?谢谢@Rahulrr2602提供赏金。我更新了答案,希望现在能更好地解释。谢谢你的反馈。拉杰什K,不,你不必,只有佛罗里达州ush是必需的。当您想要强制文件系统同步时,会有一些用例,但我不认为是这种情况。而且这不仅仅是特定于输出/输入流的java实现,这是一种更普遍的做法。Rajesh K,但当我再次思考时,它应该是必需的。因为您正在复制到可移动SD卡。所以想象一下ario当您的应用程序指示复制已完成,并且用户在复制完成后立即删除卡时。很简单,因为人们可能认为复制已完成,同步应将您保存在此处。这类似于windows“安全删除可移动驱动器”。但它的作用是iz确保文件系统缓存已同步。