>  Q&A  >  본문

android - 如何将assets文件复制到SD卡?

我想要把assets中的所有文件都复制到/sdcard/中,并在一个线程中完成这个操作,具体该如何做呢?

原问题:Android: How to copy files in 'assets' to sdcard?

天蓬老师天蓬老师2746일 전808

모든 응답(1)나는 대답할 것이다

  • 天蓬老师

    天蓬老师2017-04-17 11:28:15

    答:rciovati
    (最佳答案)
    通常来说,我会采用如下方法:

    private void copyAssets() {
        AssetManager assetManager = getAssets();
        String[] files = null;
        try {
            files = assetManager.list("");
        } catch (IOException e) {
            Log.e("tag", "Failed to get asset file list.", e);
        }
        for(String filename : files) {
            InputStream in = null;
            OutputStream out = null;
            try {
              in = assetManager.open(filename);
              File outFile = new File(getExternalFilesDir(null), filename);
              out = new FileOutputStream(outFile);
              copyFile(in, out);
              in.close();
              in = null;
              out.flush();
              out.close();
              out = null;
            } catch(IOException e) {
                Log.e("tag", "Failed to copy asset file: " + filename, e);
            }       
        }
    }
    private void copyFile(InputStream in, OutputStream out) throws IOException {
        byte[] buffer = new byte[1024];
        int read;
        while((read = in.read(buffer)) != -1){
          out.write(buffer, 0, read);
        }
    }
    

    答:DannyA
    基于上述方法,我做了一些调整,以便于将数据可以导入子文件夹:
    ...

    copyFileOrDir("myrootdir");
    

    ...

    private void copyFileOrDir(String path) {
        AssetManager assetManager = this.getAssets();
        String assets[] = null;
        try {
            assets = assetManager.list(path);
            if (assets.length == 0) {
                copyFile(path);
            } else {
                String fullPath = "/data/data/" + this.getPackageName() + "/" + path;
                File dir = new File(fullPath);
                if (!dir.exists())
                    dir.mkdir();
                for (int i = 0; i < assets.length; ++i) {
                    copyFileOrDir(path + "/" + assets[i]);
                }
            }
        } catch (IOException ex) {
            Log.e("tag", "I/O Exception", ex);
        }
    }
    
    private void copyFile(String filename) {
        AssetManager assetManager = this.getAssets();
    
        InputStream in = null;
        OutputStream out = null;
        try {
            in = assetManager.open(filename);
            String newFileName = "/data/data/" + this.getPackageName() + "/" + filename;
            out = new FileOutputStream(newFileName);
    
            byte[] buffer = new byte[1024];
            int read;
            while ((read = in.read(buffer)) != -1) {
                out.write(buffer, 0, read);
            }
            in.close();
            in = null;
            out.flush();
            out.close();
            out = null;
        } catch (Exception e) {
            Log.e("tag", e.getMessage());
        }
    
    }
    

    答:JPM
    我知道这个问题有很多人解答过,但是我有一个相对来说更便捷的方法可以直接将asset中的文件复制到sdcard,它不需要进行“for”循环语句,但还是要用到File Streams和Channels。

    AssetManager am = context.getAssets();
    AssetFileDescriptor afd = null;
    try {
        afd = am.openFd( "MyFile.dat");
    
        // Create new file to copy into.
        File file = new File(Environment.getExternalStorageDirectory() + java.io.File.separator + "NewFile.dat");
        file.createNewFile();
    
        copyFdToFile(afd.getFileDescriptor(), file);
    
    } catch (IOException e) {
        e.printStackTrace();
    }
    

    不需要循环的复制文件方法:

    public static void copyFdToFile(FileDescriptor 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();
        }
    }
    

    答:gnac
    我的建议是采用“for”循环语句,方法如下:

    for(String filename : files) {
            InputStream in = null;
            OutputStream out = null;
            try {
              in = assetManager.open(filename);
              out = new FileOutputStream("/sdcard/" + filename);
            ...
        }
    

    회신하다
    0
  • 취소회신하다