ในแอพของฉันฉันต้องการบันทึกสำเนาของไฟล์ที่มีชื่ออื่น (ซึ่งฉันได้รับจากผู้ใช้)
ฉันจำเป็นต้องเปิดเนื้อหาของไฟล์และเขียนลงในไฟล์อื่นหรือไม่?
วิธีที่ดีที่สุดที่จะทำคืออะไร?
ในแอพของฉันฉันต้องการบันทึกสำเนาของไฟล์ที่มีชื่ออื่น (ซึ่งฉันได้รับจากผู้ใช้)
ฉันจำเป็นต้องเปิดเนื้อหาของไฟล์และเขียนลงในไฟล์อื่นหรือไม่?
วิธีที่ดีที่สุดที่จะทำคืออะไร?
คำตอบ:
ในการคัดลอกไฟล์และบันทึกไว้ในเส้นทางปลายทางของคุณคุณสามารถใช้วิธีการด้านล่าง
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 Automatic Resource Management:
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);
}
}
}
}
หรือคุณสามารถใช้FileChannelเพื่อคัดลอกไฟล์ มันอาจจะเร็วกว่าวิธีการคัดลอกไบต์เมื่อคัดลอกไฟล์ขนาดใหญ่ คุณไม่สามารถใช้งานได้หากไฟล์ของคุณมีขนาดใหญ่กว่า 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);ขั้นตอน ตามข้อความที่ฉันรู้ว่าไฟล์ไม่มีอยู่ฉันจึงตรวจสอบและโทร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) ) {
onProgressUpdateดังนั้นฉันสามารถแสดงใน ProgressBar ได้หรือไม่ ในโซลูชันที่ยอมรับฉันสามารถคำนวณความคืบหน้าได้ในขณะที่วนรอบ แต่ฉันไม่เห็นวิธีการทำที่นี่
ขยาย Kotlin สำหรับมัน
fun File.copyTo(file: File) {
inputStream().use { input ->
file.outputStream().use { output ->
input.copyTo(output)
}
}
}
contentResolver.openInputStream(uri)คำตอบง่ายล้มเหลวในการบัญชีสำหรับยูริเปิดผ่าน
สิ่งเหล่านี้ใช้ได้ดีสำหรับฉัน
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();
}
}
}
นี่เป็นเรื่องง่ายบน 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());
}
มันอาจจะสายเกินไปสำหรับคำตอบ แต่วิธีที่สะดวกที่สุดคือการใช้
FileUtils's
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:
File("originalFileDir", "originalFile.name")
.copyTo(File("newFileDir", "newFile.name"), true)
trueหรือใช้falseสำหรับเขียนทับไฟล์ปลายทาง
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/java.io.-file/copy-to.html
นี่คือวิธีการแก้ปัญหาที่ปิดช่องรับ - ส่งสัญญาณจริงหากเกิดข้อผิดพลาดขณะคัดลอก วิธีการแก้ปัญหานี้ใช้วิธีการ 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 เพียง:
val fileSrc : File = File("srcPath")
val fileDest : File = File("destPath")
fileSrc.copyTo(fileDest)