En mi aplicación, quiero guardar una copia de un determinado archivo con un nombre diferente (que obtengo del usuario)
¿Realmente necesito abrir el contenido del archivo y escribirlo en otro archivo?
¿Cual es la mejor manera de hacerlo?
En mi aplicación, quiero guardar una copia de un determinado archivo con un nombre diferente (que obtengo del usuario)
¿Realmente necesito abrir el contenido del archivo y escribirlo en otro archivo?
¿Cual es la mejor manera de hacerlo?
Para copiar un archivo y guardarlo en su ruta de destino, puede usar el siguiente método.
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();
}
}
En API 19+ puedes usar 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);
}
}
}
}
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.
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)
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"/>
.
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
fun File.copyTo(file: File) {
inputStream().use { input ->
file.outputStream().use { output ->
input.copyTo(output)
}
}
}
contentResolver.openInputStream(uri)
.
Esto funcionó bien para mí
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();
}
}
}
Esto es simple en Android O (API 26), como puede ver:
@RequiresApi(api = Build.VERSION_CODES.O)
public static void copy(File origin, File dest) throws IOException {
Files.copy(origin.toPath(), dest.toPath());
}
Puede ser demasiado tarde para una respuesta, pero la forma más conveniente es usar
FileUtils
's
static void copyFile(File srcFile, File destFile)
por ejemplo, esto es lo que hice
``
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;
}
``
Mucho más simple ahora con Kotlin:
File("originalFileDir", "originalFile.name")
.copyTo(File("newFileDir", "newFile.name"), true)
true
o false
es para sobrescribir el archivo de destino
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/java.io.-file/copy-to.html
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.
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);
}
}
en kotlin, solo:
val fileSrc : File = File("srcPath")
val fileDest : File = File("destPath")
fileSrc.copyTo(fileDest)