How to move/rename file from internal app storage to external storage on Android?
I am downloading files from the internet and saving the streaming data to a temp file in my app's internal storage given by getFilesDir().
Once the download is complete, I need to move the temp file to my download directory on External Memory (usually an SD Card). For some reason though, File.renameTo() isn't working for this. I'm gues开发者_开发知识库sing there's a problem because it's two separate file systems, but I can still download directly to the SD Card and the file URIs are correct.
Is there another simple and quick way to transfer that file from internal memory to external or do I have to do a byte stream copy and delete the original?
To copy files from internal memory to SD card and vice-versa using following piece of code:
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();
}
}
And - it works...
Internal and external memory is two different file systems. Therefore renameTo() fails.
You will have to copy the file and delete the original
After you copy the file (as @barmaley's great answer shows), don't forget to expose it to the device's gallery, so the user can view it later.
The reason why it has to be done manually is that
Android runs a full media scan only on reboot and when (re)mounting the SD card
(as this guide shows).
The easier way to do this is by sending a broadcast for the scanning to be invoked:
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(Uri.fromFile(outputFile));
context.sendBroadcast(intent);
And voila! You can now view your file in the device's gallery.
An alternative to the copying using your own function is to use Apache's library's class "FileUtils" , in the function called copyFile :
FileUtils.copyFile(src, dst, true);
Did some trivial modifications to @barmaley's code
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;
}
Picture that:
- This is internal path : pathInternal
- And this is external path : pathExternal
Try with this code:
public void moveIn (String pathInternal, String pathExternal) {
File fInternal = new File (pathInternal);
File fExternal = new File (pathExternal);
if (fInternal.exists()) {
fInternal.renameTo(fExternal);
}
}
You can do it using operations with byte[]
define in your class:
public static final String DATA_PATH =
Environment.getExternalStorageDirectory().toString() + "/MyAppName/";
then:
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();
For Move file best way is Renaming it's path with different path and name example:
File from = new File(Environment.getExternalStorage().getAbsolutePath()+"/kaic1/imagem.jpg");
File to = new File(Environment.getExternalStorage().getAbsolutePath()+"/kaic2/imagem.jpg");
from.renameTo(to);
精彩评论