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

 暗影HK4164286 发布于 2022-11-05 19:01

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

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

1 个回答
  • 答: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);
            ...
        }
    
    2022-11-10 08:27 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有