如何在Android上将文件从内部应用程序存储移动/重命名为外部存储?

时间:2011-01-22 19:18:39

标签: java android file

我正在从互联网上下载文件,并将流式数据保存到getFilesDir()给出的应用内部存储空间中的临时文件中。

下载完成后,我需要将临时文件移动到外部存储器上的下载目录(通常是SD卡)。但由于某种原因,File.renameTo()不适用于此。我猜这是一个问题,因为它是两个独立的文件系统,但我仍然可以直接下载到SD卡,文件URI是正确的。

还有另一种简单快捷的方法可以将该文件从内部存储器传输到外部,还是我必须进行字节流复制并删除原始文件?

8 个答案:

答案 0 :(得分:82)

使用以下代码将文件从内部存储器复制到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();
    }
}

而且 - 它有效......

答案 1 :(得分:12)

内部和外部存储器是两个不同的文件系统。因此renameTo()失败。

您必须复制文件并删除原始文件

答案 2 :(得分:10)

复制文件后(如@barmaley的精彩答案所示),请勿忘记将其公开到设备的图库,以便用户稍后查看。

必须手动完成的原因是

  

Android仅在重新启动和重新安装时运行完整的媒体扫描   SD卡

(如this guide所示)。

更简单的方法是通过发送广播来调用扫描:

Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(Uri.fromFile(outputFile));
context.sendBroadcast(intent);

瞧!您现在可以在设备的图库中查看文件。

答案 3 :(得分:3)

使用自己的函数进行复制的另一种方法是在名为copyFile的函数中使用Apache的库“FileUtils”:

FileUtils.copyFile(src, dst, true);

答案 4 :(得分:0)

对@ 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;
    }

答案 5 :(得分:0)

想象一下:

  • 这是内部路径: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);
    }
}

答案 6 :(得分:0)

您可以使用 byte []

进行操作

在你的班级中定义:

    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();

答案 7 :(得分:-1)

对于移动文件,最好的方法是使用不同的路径和名称重命名它的路径 例如:

File from = new File(Environment.getExternalStorage().getAbsolutePath()+"/kaic1/imagem.jpg");
File to = new File(Environment.getExternalStorage().getAbsolutePath()+"/kaic2/imagem.jpg");
from.renameTo(to);