Как переместить/переименовать файл из внутреннего хранилища приложений во внешнее хранилище на Android?
Я загружаю файлы из Интернета и сохраняю потоковые данные во временном файле в моем внутреннем хранилище приложений, указанном getFilesDir().
Как только загрузка будет завершена, мне нужно переместить файл temp в каталог загрузки в External Memory (обычно SD-карту). По какой-то причине File.renameTo() не работает для этого. Я предполагаю, что есть проблема, потому что это две отдельные файловые системы, но я все равно могу загрузить их прямо на SD-карту, и URI файлов верны.
Есть ли еще простой и быстрый способ переноса этого файла из внутренней памяти на внешний или мне нужно сделать копию байтового потока и удалить оригинал?
Ответы
Ответ 1
Чтобы скопировать файлы из внутренней памяти на SD-карту и наоборот, используя следующий фрагмент кода:
public static void copyFile(File src, File dst) throws IOException
{
FileChannel inChannel = new FileInputStream(src).getChannel();
FileChannel outChannel = new FileOutputStream(dst).getChannel();
try
{
inChannel.transferTo(0, inChannel.size(), outChannel);
}
finally
{
if (inChannel != null)
inChannel.close();
if (outChannel != null)
outChannel.close();
}
}
И - он работает...
Ответ 2
Внутренняя и внешняя память - это две разные файловые системы. Поэтому renameTo() терпит неудачу.
Вам нужно будет скопировать файл и удалить оригинал
Ответ 3
После того, как вы скопируете файл (как @barmaley отличный ответ), не забудьте выставить его в галерее устройств, чтобы пользователь мог просмотреть его позже,
Причина, по которой это нужно сделать вручную, заключается в том, что
Android запускает полное сканирование мультимедиа только при перезагрузке и при повторном монтаже SD-карта
(как данное руководство).
Более простой способ сделать это - отправить широковещательную рассылку для вызываемого сканирования:
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(Uri.fromFile(outputFile));
context.sendBroadcast(intent);
И вуаля! Теперь вы можете просмотреть свой файл в галерее устройств.
Ответ 4
Альтернативой копированию с использованием вашей собственной функции является использование класса библиотеки Apache "FileUtils" в функции copyFile:
FileUtils.copyFile(src, dst, true);
Ответ 5
Для Move file лучший способ - переименовать его путь с другим путем и именем
Пример:
File from = new File(Environment.getExternalStorage().getAbsolutePath()+"/kaic1/imagem.jpg");
File to = new File(Environment.getExternalStorage().getAbsolutePath()+"/kaic2/imagem.jpg");
from.renameTo(to);
Ответ 6
Изображение:
- Это внутренний путь: pathInternal
- И это внешний путь:
pathExternal
Попробуйте с помощью этого кода:
public void moveIn (String pathInternal, String pathExternal) {
File fInternal = new File (pathInternal);
File fExternal = new File (pathExternal);
if (fInternal.exists()) {
fInternal.renameTo(fExternal);
}
}
Ответ 7
Были ли некоторые тривиальные модификации кода @barmaley
public boolean copyFile(File src, File dst) {
boolean returnValue = true;
FileChannel inChannel = null, outChannel = null;
try {
inChannel = new FileInputStream(src).getChannel();
outChannel = new FileOutputStream(dst).getChannel();
} catch (FileNotFoundException fnfe) {
Log.d(logtag, "inChannel/outChannel FileNotFoundException");
fnfe.printStackTrace();
return false;
}
try {
inChannel.transferTo(0, inChannel.size(), outChannel);
} catch (IllegalArgumentException iae) {
Log.d(logtag, "TransferTo IllegalArgumentException");
iae.printStackTrace();
returnValue = false;
} catch (NonReadableChannelException nrce) {
Log.d(logtag, "TransferTo NonReadableChannelException");
nrce.printStackTrace();
returnValue = false;
} catch (NonWritableChannelException nwce) {
Log.d(logtag, "TransferTo NonWritableChannelException");
nwce.printStackTrace();
returnValue = false;
} catch (ClosedByInterruptException cie) {
Log.d(logtag, "TransferTo ClosedByInterruptException");
cie.printStackTrace();
returnValue = false;
} catch (AsynchronousCloseException ace) {
Log.d(logtag, "TransferTo AsynchronousCloseException");
ace.printStackTrace();
returnValue = false;
} catch (ClosedChannelException cce) {
Log.d(logtag, "TransferTo ClosedChannelException");
cce.printStackTrace();
returnValue = false;
} catch (IOException ioe) {
Log.d(logtag, "TransferTo IOException");
ioe.printStackTrace();
returnValue = false;
} finally {
if (inChannel != null)
try {
inChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
if (outChannel != null)
try {
outChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return returnValue;
}
Ответ 8
Вы можете сделать это, используя операции с байт []
определите в своем классе:
public static final String DATA_PATH =
Environment.getExternalStorageDirectory().toString() + "/MyAppName/";
то
AssetManager assetManager = context.getAssets();
InputStream in = assetManager.open("data/file.txt");
OutputStream out = new FileOutputStream(DATA_PATH + "data/file.txt");
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();