Para copiar un archivo y guardarlo en su ruta de destino, puede usar el siguiente método.
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();}}
En API 19+ puedes usar Java Automatic Resource Management:
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);}}}}
Gracias. Después de golpearme la cabeza, descubrí que al problema le faltaba permiso para escribir en almacenamiento externo. Ahora funciona bien.
COMO
8
@ mohitum007 si el archivo no se copia, se genera una excepción. use un bloque try catch cuando llame al método.
Nima G
9
Si se produce una excepción, los flujos no se cerrarán hasta que se recolecte basura, y eso no es bueno . Considere cerrarlos finally.
Pang
1
@Angustia. Tienes razón. Lo que es peor, se debe llamar a in / out.close () o, de lo contrario, habrá una fuga de recursos en el sistema operativo subyacente, ya que el GC nunca cerrará los descriptores de archivos abiertos. GC no puede cerrar los recursos del sistema operativo externos a la JVM como descriptores de archivos o sockets. Esos siempre deben cerrarse en una cláusula final programáticamente o usar una nueva sintaxis de prueba con recursos: docs.oracle.com/javase/tutorial/essential/exceptions/…
earizon
44
Por favor, cierre ambas secuencias dentro de un finalmente, si hay una excepción, la memoria de sus secuencias no se recopilará.
transferTo puede lanzar una excepción y, en ese caso, dejará las transmisiones abiertas. Al igual que Pang y Nima comentaron en respuesta aceptada.
Viktor Brešan
Además, transferTo debe llamarse dentro del bucle ya que no garantiza que transferirá la cantidad total solicitada.
Viktor Brešan
Probé su solución y me falla con la excepción java.io.FileNotFoundException: /sdcard/AppProj/IMG_20150626_214946.jpg: open failed: ENOENT (No such file or directory)en el FileOutputStream outStream = new FileOutputStream(dst);paso. De acuerdo con el texto, me doy cuenta de que el archivo no existe, así que lo reviso y llamo dst.mkdir();si es necesario, pero todavía no ayuda. También traté de verificar dst.canWrite();y regresó false. ¿Puede esta es la fuente del problema? Y sí, tengo <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>.
Mike B.
1
@ ViktorBrešan Después de API 19, puede utilizar la gestión automática de recursos de Java definiendo las secuencias de entrada y salida en la apertura de su intentotry ( FileInputStream inStream = new FileInputStream(src); FileOutputStream outStream = new FileOutputStream(dst) ) {
AlbertMarkovski
¿Hay alguna forma de hacer que esta solución publique su progreso para onProgressUpdatepoder mostrarla en una barra de progreso? En la solución aceptada puedo calcular el progreso en el ciclo while, pero no puedo ver cómo hacerlo aquí.
Esta es la respuesta más concisa pero flexible. Las respuestas más simples no tienen en cuenta los URI abiertos a través de contentResolver.openInputStream(uri).
No es tan simple si su archivo proviene de una intención de galería Uri.
AjahnCharles
Lea los comentarios a continuación que responden: "Esta respuesta es activamente dañina y no merece los votos que recibe. Falla si el Uri es un contenido: // o cualquier otro Uri que no sea de archivo". (
Voté a favor,
5
Aquí hay una solución que realmente cierra las secuencias de entrada / salida si se produce un error durante la copia. Esta solución utiliza los métodos Apache Commons IO IOUtils para copiar y manejar el cierre de flujos.
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);}}
Respuestas:
Para copiar un archivo y guardarlo en su ruta de destino, puede usar el siguiente método.
En API 19+ puedes usar Java Automatic Resource Management:
fuente
finally
.Alternativamente, puede usar FileChannel para copiar un archivo. Se podría ser más rápido que el método de copia de bytes cuando se copia un archivo grande. Sin embargo, no puede usarlo si su archivo es más grande que 2GB.
fuente
java.io.FileNotFoundException: /sdcard/AppProj/IMG_20150626_214946.jpg: open failed: ENOENT (No such file or directory)
en elFileOutputStream outStream = new FileOutputStream(dst);
paso. De acuerdo con el texto, me doy cuenta de que el archivo no existe, así que lo reviso y llamodst.mkdir();
si es necesario, pero todavía no ayuda. También traté de verificardst.canWrite();
y regresófalse
. ¿Puede esta es la fuente del problema? Y sí, tengo<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
.try ( FileInputStream inStream = new FileInputStream(src); FileOutputStream outStream = new FileOutputStream(dst) ) {
onProgressUpdate
poder mostrarla en una barra de progreso? En la solución aceptada puedo calcular el progreso en el ciclo while, pero no puedo ver cómo hacerlo aquí.Extensión de Kotlin para ello
fuente
contentResolver.openInputStream(uri)
.Esto funcionó bien para mí
fuente
Esto es simple en Android O (API 26), como puede ver:
fuente
Puede ser demasiado tarde para una respuesta, pero la forma más conveniente es usar
FileUtils
'sstatic void copyFile(File srcFile, File destFile)
por ejemplo, esto es lo que hice
``
``
fuente
Mucho más simple ahora con Kotlin:
true
ofalse
es para sobrescribir el archivo de destinohttps://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/java.io.-file/copy-to.html
fuente
Aquí hay una solución que realmente cierra las secuencias de entrada / salida si se produce un error durante la copia. Esta solución utiliza los métodos Apache Commons IO IOUtils para copiar y manejar el cierre de flujos.
fuente
en kotlin, solo:
fuente