Nella mia app voglio salvare una copia di un determinato file con un nome diverso (che ottengo dall'utente)
Devo davvero aprire il contenuto del file e scriverlo su un altro file?
Qual è il modo migliore per farlo?
Nella mia app voglio salvare una copia di un determinato file con un nome diverso (che ottengo dall'utente)
Devo davvero aprire il contenuto del file e scriverlo su un altro file?
Qual è il modo migliore per farlo?
Risposte:
Per copiare un file e salvarlo sul percorso di destinazione è possibile utilizzare il metodo seguente.
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();
}
}
Su API 19+ puoi utilizzare 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.
In alternativa, è possibile utilizzare FileChannel per copiare un file. Si potrebbe essere più veloce rispetto al metodo di copia di byte quando si copia un file di grandi dimensioni. Non puoi usarlo se il tuo file è più grande di 2 GB però.
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)del FileOutputStream outStream = new FileOutputStream(dst);passaggio. Secondo il testo, mi rendo conto che il file non esiste, quindi lo controllo e lo chiamo dst.mkdir();se necessario, ma non aiuta ancora. Ho anche provato a controllare dst.canWrite();ed è tornato false. Può questa essere la fonte del problema? E sì, l'ho fatto <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>.
try ( FileInputStream inStream = new FileInputStream(src); FileOutputStream outStream = new FileOutputStream(dst) ) {
onProgressUpdate, in modo che io possa mostrarlo in ProgressBar? Nella soluzione accettata posso calcolare i progressi nel ciclo while, ma non riesco a vedere come farlo qui.
Estensione Kotlin per questo
fun File.copyTo(file: File) {
inputStream().use { input ->
file.outputStream().use { output ->
input.copyTo(output)
}
}
}
contentResolver.openInputStream(uri).
Questi hanno funzionato bene per me
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();
}
}
}
Potrebbe essere troppo tardi per una risposta, ma il modo più conveniente è usare
FileUtils'S
static void copyFile(File srcFile, File destFile)
ad esempio questo è quello che ho fatto
`
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;
}
`
Molto più semplice ora con Kotlin:
File("originalFileDir", "originalFile.name")
.copyTo(File("newFileDir", "newFile.name"), true)
trueo falseserve per sovrascrivere il file di destinazione
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/java.io.-file/copy-to.html
Ecco una soluzione che chiude effettivamente i flussi di input / output se si verifica un errore durante la copia. Questa soluzione utilizza i metodi IO IOUtils di Apache Commons sia per la copia che per la gestione della chiusura di flussi.
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);
}
}