Чтобы скопировать файл и сохранить его по своему пути назначения, вы можете использовать метод ниже.
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();}}
В API 19+ вы можете использовать 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);}}}}
Спасибо. после удара головой я обнаружил, что проблема заключается в отсутствии разрешения на запись во внешнее хранилище. сейчас работает нормально.
AS
8
@ mohitum007 если файл не удается скопировать, возникает исключение. используйте блок try catch при вызове метода.
Нима Г
9
Если выдается исключение, потоки не будут закрыты до тех пор, пока не будут собраны сборщики мусора, и это не хорошо . Рассмотрите возможность их закрытия finally.
Панг
1
@Pang. Ты прав. Что еще хуже, должна вызываться in / out.close (), иначе в базовой ОС будет утечка ресурсов, поскольку GC никогда не закроет дескрипторы открытого файла. GC не может закрывать ресурсы ОС, внешние по отношению к JVM, такие как дескрипторы файлов или сокеты. Они должны всегда закрываться в предложении finally программно или использовать новый синтаксис try-with-resource: docs.oracle.com/javase/tutorial/essential/exceptions/…
earizon
4
Пожалуйста, закройте оба потока внутри, наконец, если есть исключение, память ваших потоков не будет собрана.
TransferTo может выдать исключение, и в этом случае вы оставляете потоки открытыми. Также как Панг и Нима прокомментировали принятый ответ.
Виктор Брешан
Кроме того, TransferTo должен вызываться внутри цикла, так как он не гарантирует, что он переведет всю запрошенную сумму.
Виктор Брешан
Я попробовал ваше решение , и оно не для меня, за исключением java.io.FileNotFoundException: /sdcard/AppProj/IMG_20150626_214946.jpg: open failed: ENOENT (No such file or directory)на FileOutputStream outStream = new FileOutputStream(dst);этапе. По тексту я понимаю, что файл не существует, поэтому я проверяю его и dst.mkdir();при необходимости вызываю , но это все равно не помогает. Я тоже пытался проверить, dst.canWrite();и он вернулся false. Может ли это источник проблемы? И да, у меня есть <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>.
Майк Б.
1
@ ViktorBrešan После API 19 вы можете использовать автоматическое управление ресурсами Java, определяя try ( FileInputStream inStream = new FileInputStream(src); FileOutputStream outStream = new FileOutputStream(dst) ) {
входные и выходные
Есть ли способ заставить это решение опубликовать свой прогресс onProgressUpdate, чтобы я мог показать его в ProgressBar? В принятом решении я могу вычислить прогресс в цикле while, но не вижу, как это сделать здесь.
Не все так просто, если ваш файл исходит из намерения галереи Uri.
AjahnCharles
Прочитайте приведенные ниже комментарии к этому ответу: «Этот ответ активно вреден и не заслуживает тех голосов, которые он получил. Он потерпит неудачу, если Uri является контентом: // или любым другим нефайловым Uri». (Я сделал upvote - я просто хотел уточнить, что это не серебряная пуля)
AjahnCharles
5
Вот решение, которое фактически закрывает потоки ввода / вывода, если при копировании возникает ошибка. Это решение использует методы Apache Commons IO IOUtils для копирования и обработки закрытия потоков.
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);}}
Ответы:
Чтобы скопировать файл и сохранить его по своему пути назначения, вы можете использовать метод ниже.
В API 19+ вы можете использовать Java Automatic Resource Management:
источник
finally
.Кроме того, вы можете использовать FileChannel для копирования файла. Это может быть быстрее, чем метод байтового копирования при копировании большого файла. Вы не можете использовать его, если ваш файл больше 2 ГБ.
источник
java.io.FileNotFoundException: /sdcard/AppProj/IMG_20150626_214946.jpg: open failed: ENOENT (No such file or directory)
наFileOutputStream outStream = new FileOutputStream(dst);
этапе. По тексту я понимаю, что файл не существует, поэтому я проверяю его иdst.mkdir();
при необходимости вызываю , но это все равно не помогает. Я тоже пытался проверить,dst.canWrite();
и он вернулсяfalse
. Может ли это источник проблемы? И да, у меня есть<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
.try ( FileInputStream inStream = new FileInputStream(src); FileOutputStream outStream = new FileOutputStream(dst) ) {
onProgressUpdate
, чтобы я мог показать его в ProgressBar? В принятом решении я могу вычислить прогресс в цикле while, но не вижу, как это сделать здесь.Удлинение Kotlin для этого
источник
contentResolver.openInputStream(uri)
.Это работало хорошо для меня
источник
Это просто на Android O (API 26), как вы видите:
источник
Возможно, уже слишком поздно для ответа, но самый удобный способ
FileUtils
«sstatic void copyFile(File srcFile, File destFile)
например, это то, что я сделал
`
`
источник
Намного проще теперь с Kotlin:
true
илиfalse
для перезаписи файла назначенияhttps://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/java.io.-file/copy-to.html
источник
Вот решение, которое фактически закрывает потоки ввода / вывода, если при копировании возникает ошибка. Это решение использует методы Apache Commons IO IOUtils для копирования и обработки закрытия потоков.
источник
в котлине, просто:
источник