In meiner App möchte ich eine Kopie einer bestimmten Datei unter einem anderen Namen speichern (den ich vom Benutzer erhalte).
Muss ich den Inhalt der Datei wirklich öffnen und in eine andere Datei schreiben?
Was ist der beste Weg, dies zu tun?
In meiner App möchte ich eine Kopie einer bestimmten Datei unter einem anderen Namen speichern (den ich vom Benutzer erhalte).
Muss ich den Inhalt der Datei wirklich öffnen und in eine andere Datei schreiben?
Was ist der beste Weg, dies zu tun?
Antworten:
Um eine Datei zu kopieren und in Ihrem Zielpfad zu speichern, können Sie die folgende Methode verwenden.
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();
}
}
Ab API 19+ können Sie Java Automatic Resource Management verwenden:
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
.
Alternativ können Sie FileChannel verwenden, um eine Datei zu kopieren. Es ist möglicherweise schneller als die Byte-Kopiermethode beim Kopieren einer großen Datei. Sie können es jedoch nicht verwenden, wenn Ihre Datei größer als 2 GB ist.
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)
des FileOutputStream outStream = new FileOutputStream(dst);
Schrittes fehl . Laut dem Text ist mir klar, dass die Datei nicht existiert, also überprüfe ich sie und rufe dst.mkdir();
bei Bedarf auf, aber es hilft immer noch nicht. Ich habe auch versucht zu überprüfen dst.canWrite();
und es kehrte zurück false
. Darf dies die Ursache des Problems sein? Und ja, das habe ich <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
.
try ( FileInputStream inStream = new FileInputStream(src); FileOutputStream outStream = new FileOutputStream(dst) ) {
onProgressUpdate
, damit ich sie in einer ProgressBar anzeigen kann? In der akzeptierten Lösung kann ich den Fortschritt in der while-Schleife berechnen, aber ich kann hier nicht sehen, wie es geht.
Kotlin Erweiterung dafür
fun File.copyTo(file: File) {
inputStream().use { input ->
file.outputStream().use { output ->
input.copyTo(output)
}
}
}
contentResolver.openInputStream(uri)
.
Diese haben gut für mich funktioniert
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();
}
}
}
Für eine Antwort ist es möglicherweise zu spät, aber der bequemste Weg ist die Verwendung
FileUtils
's
static void copyFile(File srcFile, File destFile)
zB habe ich das getan
`
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;
}
`
Mit Kotlin jetzt viel einfacher:
File("originalFileDir", "originalFile.name")
.copyTo(File("newFileDir", "newFile.name"), true)
true
oder false
dient zum Überschreiben der Zieldatei
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/java.io.-file/copy-to.html
Hier ist eine Lösung, die die Eingabe- / Ausgabestreams tatsächlich schließt, wenn beim Kopieren ein Fehler auftritt. Diese Lösung verwendet Apache Commons IO IOUtils-Methoden zum Kopieren und Behandeln des Schließens von Streams.
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);
}
}