簡體   English   中英

如何在Android上將文件從內部應用程序存儲移動/重命名為外部存儲?

[英]How to move/rename file from internal app storage to external storage on Android?

我正在從互聯網上下載文件並將流數據保存到我的應用程序內部存儲中的臨時文件中,由getFilesDir()給出。

下載完成后,我需要將臨時文件移動到外部存儲器(通常是SD卡)上的下載目錄。 但由於某種原因,File.renameTo()不適用於此。 我猜這是一個問題,因為它是兩個獨立的文件系統,但我仍然可以直接下載到SD卡,文件URI是正確的。

是否有另一種簡單快捷的方法將文件從內部存儲器傳輸到外部,或者我是否必須進行字節流復制並刪除原始文件?

使用以下代碼將文件從內部存儲器復制到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();
    }
}

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

內部和外部存儲器是兩個不同的文件系統。 因此renameTo()失敗。

您必須復制文件並刪除原始文件

復制文件后(如@barmaley的精彩答案所示),不要忘記將其公開給設備的圖庫,以便用戶以后查看。

它必須手動完成的原因是

Android僅在重新啟動時以及(重新)安裝SD卡時運行完整介質掃描

(如本指南所示)。

更簡單的方法是通過發送廣播來調用掃描:

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

瞧! 您現在可以在設備的庫中查看您的文件。

使用自己的函數進行復制的另一種方法是在名為copyFile的函數中使用Apache的庫“ FileUtils”

FileUtils.copyFile(src, dst, true);

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

想象一下:

  • 這是內部路徑: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);
    }
}

你可以使用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();

對於Move文件,最好的方法是使用不同的路徑和名稱示例重命名它的路徑:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM