Trong ứng dụng của mình, tôi muốn lưu một bản sao của một tệp nhất định có tên khác (mà tôi nhận được từ người dùng)
Tôi có thực sự cần phải mở nội dung của tập tin và ghi nó vào tập tin khác không?
Cách tốt nhất để làm như vậy là gì?
Trong ứng dụng của mình, tôi muốn lưu một bản sao của một tệp nhất định có tên khác (mà tôi nhận được từ người dùng)
Tôi có thực sự cần phải mở nội dung của tập tin và ghi nó vào tập tin khác không?
Cách tốt nhất để làm như vậy là gì?
Câu trả lời:
Để sao chép một tập tin và lưu nó vào đường dẫn đích của bạn, bạn có thể sử dụng phương pháp bên dưới.
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();
}
}
Trên API 19+, bạn có thể sử dụng Quản lý tài nguyên tự động 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
.
Ngoài ra, bạn có thể sử dụng FileChannel để sao chép tệp. Nó có thể nhanh hơn phương thức sao chép byte khi sao chép một tệp lớn. Bạn không thể sử dụng nó nếu tập tin của bạn lớn hơn 2GB.
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);
bước này. Theo văn bản tôi nhận ra, tập tin không tồn tại, vì vậy tôi kiểm tra nó và gọi dst.mkdir();
nếu cần, nhưng nó vẫn không giúp được gì. Tôi cũng đã thử kiểm tra dst.canWrite();
và nó trở lại false
. Đây có thể là nguồn gốc của vấn đề? Và vâng, tôi có <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
.
try ( FileInputStream inStream = new FileInputStream(src); FileOutputStream outStream = new FileOutputStream(dst) ) {
onProgressUpdate
, vì vậy tôi có thể hiển thị nó trong ProgressBar không? Trong giải pháp được chấp nhận, tôi có thể tính toán tiến trình trong vòng lặp while, nhưng tôi không thể thấy cách thực hiện ở đây.
Phần mở rộng của Kotlin cho nó
fun File.copyTo(file: File) {
inputStream().use { input ->
file.outputStream().use { output ->
input.copyTo(output)
}
}
}
contentResolver.openInputStream(uri)
.
Chúng làm việc tốt cho tôi
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();
}
}
}
Có thể đã quá muộn để trả lời nhưng cách thuận tiện nhất là sử dụng
FileUtils
'S
static void copyFile(File srcFile, File destFile)
ví dụ như đây là những gì tôi đã làm
`
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;
}
`
Bây giờ đơn giản hơn nhiều với Kotlin:
File("originalFileDir", "originalFile.name")
.copyTo(File("newFileDir", "newFile.name"), true)
true
hoặc false
là để ghi đè tập tin đích
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/java.io.-file/copy-to.html
Đây là một giải pháp thực sự đóng các luồng đầu vào / đầu ra nếu xảy ra lỗi trong khi sao chép. Giải pháp này sử dụng các phương thức apache Commons IO IOUtils cho cả sao chép và xử lý việc đóng luồng.
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);
}
}