Um eine Datei zu kopieren und in Ihrem Zielpfad zu speichern, können Sie die folgende Methode verwenden.
publicstaticvoid copy(File src,File dst)throwsIOException{InputStream in =newFileInputStream(src);try{OutputStream out =newFileOutputStream(dst);try{// Transfer bytes from in to outbyte[] buf =newbyte[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:
publicstaticvoid copy(File src,File dst)throwsIOException{try(InputStream in =newFileInputStream(src)){try(OutputStream out =newFileOutputStream(dst)){// Transfer bytes from in to outbyte[] buf =newbyte[1024];int len;while((len = in.read(buf))>0){
out.write(buf,0, len);}}}}
Danke dir. Nachdem ich mir den Kopf geschlagen hatte, stellte ich fest, dass das Problem darin bestand, dass ich nicht in den externen Speicher schreiben durfte. jetzt funktioniert es gut.
AS
8
@ mohitum007 Wenn die Datei nicht kopiert werden kann, wird eine Ausnahme ausgelöst. Verwenden Sie beim Aufrufen der Methode einen try catch-Block.
Nima G
9
Wenn eine Ausnahme ausgelöst wird, werden die Streams erst geschlossen, wenn der Müll gesammelt wurde, und das ist nicht gut . Erwägen Sie, sie zu schließen finally.
Pang
1
@Stich. Du hast recht. Was noch schlimmer ist, in / out.close () muss aufgerufen werden, sonst tritt im zugrunde liegenden Betriebssystem ein Ressourcenverlust auf, da der GC die offenen Dateideskriptoren niemals schließt. GC kann keine Betriebssystemressourcen außerhalb der JVM wie Dateideskriptoren oder Sockets schließen. Diese müssen immer programmgesteuert in einer finally-Klausel geschlossen werden oder die neue Syntax try-with-resource verwenden: docs.oracle.com/javase/tutorial/essential/exceptions/…
earizon
4
Bitte schließen Sie beide Streams innerhalb eines Endes. Wenn es eine Ausnahme gibt, wird Ihr Stream-Speicher nicht erfasst.
transferTo kann eine Ausnahme auslösen. In diesem Fall lassen Sie Streams offen. Genau wie Pang und Nima in akzeptierter Antwort kommentierten.
Viktor Brešan
Außerdem sollte transferTo innerhalb der Schleife aufgerufen werden, da dies nicht garantiert, dass der angeforderte Gesamtbetrag übertragen wird.
Viktor Brešan
Ich habe Ihre Lösung ausprobiert und sie schlägt für mich mit Ausnahme 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"/>.
Mike B.
1
@ ViktorBrešan Nach API 19 können Sie die automatische Ressourcenverwaltung von Java verwenden, indem Sie die try ( FileInputStream inStream = new FileInputStream(src); FileOutputStream outStream = new FileOutputStream(dst) ) {
In-
Gibt es eine Möglichkeit, diese Lösung dazu zu bringen, ihren Fortschritt zu veröffentlichen 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.
Dies ist die präziseste und zugleich flexibelste Antwort. Einfachere Antworten berücksichtigen keine URIs, die über geöffnet wurden contentResolver.openInputStream(uri).
Nicht so einfach, wenn Ihre Datei aus einer Uri-Galerie stammt.
AjahnCharles
Lesen Sie die Kommentare unter dieser Antwort: "Diese Antwort ist aktiv schädlich und verdient nicht die Stimmen, die sie erhält. Sie schlägt fehl, wenn der Uri ein Inhalt ist: // oder ein anderer Nicht-Datei-Uri." (Ich habe positiv gestimmt - ich wollte nur klarstellen, dass es keine Silberkugel ist)
AjahnCharles
5
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.
publicvoid copyFile(File src,File dst){InputStream in =null;OutputStream out =null;try{
in =newFileInputStream(src);
out =newFileOutputStream(dst);IOUtils.copy(in, out);}catch(IOException ioe){Log.e(LOGTAG,"IOException occurred.", ioe);}finally{IOUtils.closeQuietly(out);IOUtils.closeQuietly(in);}}
Antworten:
Um eine Datei zu kopieren und in Ihrem Zielpfad zu speichern, können Sie die folgende Methode verwenden.
Ab API 19+ können Sie Java Automatic Resource Management verwenden:
quelle
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.
quelle
java.io.FileNotFoundException: /sdcard/AppProj/IMG_20150626_214946.jpg: open failed: ENOENT (No such file or directory)
desFileOutputStream outStream = new FileOutputStream(dst);
Schrittes fehl . Laut dem Text ist mir klar, dass die Datei nicht existiert, also überprüfe ich sie und rufedst.mkdir();
bei Bedarf auf, aber es hilft immer noch nicht. Ich habe auch versucht zu überprüfendst.canWrite();
und es kehrte zurückfalse
. 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
quelle
contentResolver.openInputStream(uri)
.Diese haben gut für mich funktioniert
quelle
Dies ist unter Android O (API 26) einfach. Wie Sie sehen:
quelle
Für eine Antwort ist es möglicherweise zu spät, aber der bequemste Weg ist die Verwendung
FileUtils
'sstatic void copyFile(File srcFile, File destFile)
zB habe ich das getan
`
`
quelle
Mit Kotlin jetzt viel einfacher:
true
oderfalse
dient zum Überschreiben der Zieldateihttps://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/java.io.-file/copy-to.html
quelle
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.
quelle
in Kotlin nur:
quelle