【发布时间】:2012-03-06 18:27:53
【问题描述】:
在我的应用中,我想用不同的名称(我从用户那里获得)保存某个文件的副本
我真的需要打开文件的内容并将其写入另一个文件吗?
最好的方法是什么?
【问题讨论】:
-
Pre Java7,我认为答案是肯定的。 stackoverflow.com/questions/106770/….
-
查看旧版post
在我的应用中,我想用不同的名称(我从用户那里获得)保存某个文件的副本
我真的需要打开文件的内容并将其写入另一个文件吗?
最好的方法是什么?
【问题讨论】:
要复制文件并将其保存到目标路径,您可以使用以下方法。
public static void copy(File src, File dst) throws IOException {
InputStream in = new FileInputStream(src);
try {
OutputStream out = new FileOutputStream(dst);
try {
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
} finally {
out.close();
}
} finally {
in.close();
}
}
在 API 19+ 上,您可以使用 Java 自动资源管理:
public static void copy(File src, File dst) throws IOException {
try (InputStream in = new FileInputStream(src)) {
try (OutputStream out = new FileOutputStream(dst)) {
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
}
}
}
【讨论】:
finally 中关闭它们。
或者,您可以使用FileChannel 复制文件。在复制大文件时,它可能比字节复制方法快。 You can't use it if your file is bigger than 2GB though.
public void copy(File src, File dst) throws IOException {
FileInputStream inStream = new FileInputStream(src);
FileOutputStream outStream = new FileOutputStream(dst);
FileChannel inChannel = inStream.getChannel();
FileChannel outChannel = outStream.getChannel();
inChannel.transferTo(0, inChannel.size(), outChannel);
inStream.close();
outStream.close();
}
【讨论】:
java.io.FileNotFoundException: /sdcard/AppProj/IMG_20150626_214946.jpg: open failed: ENOENT (No such file or directory) 在FileOutputStream outStream = new FileOutputStream(dst); 步骤。根据我意识到的文本,该文件不存在,所以我检查它并在需要时调用dst.mkdir();,但它仍然没有帮助。我还尝试检查dst.canWrite();,它返回false。这可能是问题的根源吗?是的,我有<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>。
try ( FileInputStream inStream = new FileInputStream(src); FileOutputStream outStream = new FileOutputStream(dst) ) {987654330@ 的开头定义输入和输出流来使用 Java 自动资源管理。
onProgressUpdate,这样我就可以在 ProgressBar 中显示它?在接受的解决方案中,我可以在 while 循环中计算进度,但在这里看不到如何进行。
它的 Kotlin 扩展
fun File.copyTo(file: File) {
inputStream().use { input ->
file.outputStream().use { output ->
input.copyTo(output)
}
}
}
【讨论】:
contentResolver.openInputStream(uri) 打开的 URI。
这在 Android O (API 26) 上很简单,如您所见:
@RequiresApi(api = Build.VERSION_CODES.O)
public static void copy(File origin, File dest) throws IOException {
Files.copy(origin.toPath(), dest.toPath());
}
【讨论】:
这些对我很有效
public static void copyFileOrDirectory(String srcDir, String dstDir) {
try {
File src = new File(srcDir);
File dst = new File(dstDir, src.getName());
if (src.isDirectory()) {
String files[] = src.list();
int filesLength = files.length;
for (int i = 0; i < filesLength; i++) {
String src1 = (new File(src, files[i]).getPath());
String dst1 = dst.getPath();
copyFileOrDirectory(src1, dst1);
}
} else {
copyFile(src, dst);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void copyFile(File sourceFile, File destFile) throws IOException {
if (!destFile.getParentFile().exists())
destFile.getParentFile().mkdirs();
if (!destFile.exists()) {
destFile.createNewFile();
}
FileChannel source = null;
FileChannel destination = null;
try {
source = new FileInputStream(sourceFile).getChannel();
destination = new FileOutputStream(destFile).getChannel();
destination.transferFrom(source, 0, source.size());
} finally {
if (source != null) {
source.close();
}
if (destination != null) {
destination.close();
}
}
}
【讨论】:
现在使用 Kotlin 变得更加简单:
File("originalFileDir", "originalFile.name")
.copyTo(File("newFileDir", "newFile.name"), true)
trueorfalse 用于覆盖目标文件
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/java.io.-file/copy-to.html
【讨论】:
答案可能为时已晚,但最方便的方法是使用
FileUtils的
static void copyFile(File srcFile, File destFile)
例如这就是我所做的
`
private String copy(String original, int copyNumber){
String copy_path = path + "_copy" + copyNumber;
try {
FileUtils.copyFile(new File(path), new File(copy_path));
return copy_path;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
`
【讨论】:
在 kotlin 中,只需:
val fileSrc : File = File("srcPath")
val fileDest : File = File("destPath")
fileSrc.copyTo(fileDest)
【讨论】:
如果在复制时发生错误,这是一个实际关闭输入/输出流的解决方案。此解决方案利用 apache Commons IO IOUtils 方法来复制和处理流的关闭。
public void copyFile(File src, File dst) {
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(src);
out = new FileOutputStream(dst);
IOUtils.copy(in, out);
} catch (IOException ioe) {
Log.e(LOGTAG, "IOException occurred.", ioe);
} finally {
IOUtils.closeQuietly(out);
IOUtils.closeQuietly(in);
}
}
【讨论】:
在 Kotlin 中:一条捷径
// fromPath : Path the file you want to copy
// toPath : The path where you want to save the file
// fileName : name of the file that you want to copy
// newFileName: New name for the copied file (you can put the fileName too instead of put a new name)
val toPathF = File(toPath)
if (!toPathF.exists()) {
path.mkdir()
}
File(fromPath, fileName).copyTo(File(toPath, fileName), replace)
这适用于任何文件,例如图像和视频
【讨论】:
现在在 kotlin 中你可以使用
file1.copyTo(file2)
其中 file1 是原始文件的对象,file2 是要复制到的新文件的对象
【讨论】: