如何将文件从'资产'文件夹复制到SD卡?

assets文件夹中有几个文件。 我需要将它们全部复制到一个文件夹say / sdcard /文件夹中。 我想从一个线程内做到这一点。 我该怎么做?


如果其他人遇到同样的问题,我就是这么做的

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);
    }
    if (files != null) 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);
        } catch(IOException e) {
            Log.e("tag", "Failed to copy asset file: " + filename, e);
        }     
        finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    // NOOP
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    // NOOP
                }
            }
        }  
    }
}
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);
    }
}

参考:使用Java移动文件


根据您的解决方案,我自己做了一些事情来允许子文件夹。 有人可能会觉得这很有帮助:

...

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

}

上述解决方案由于某些错误而无法使用:

  • 目录创建不起作用
  • Android返回的资产还包含三个文件夹:图像,声音和webkit
  • 添加处理大文件的方法:将扩展名.mp3添加到项目中assets文件夹中的文件中,并且在复制期间,目标文件将不带.mp3扩展名
  • 这里是代码(我留下了Log语句,但你现在可以放下它们):

    final static String TARGET_BASE_PATH = "/sdcard/appname/voices/";
    
    private void copyFilesToSdCard() {
        copyFileOrDir(""); // copy all files in assets folder in my project
    }
    
    private void copyFileOrDir(String path) {
        AssetManager assetManager = this.getAssets();
        String assets[] = null;
        try {
            Log.i("tag", "copyFileOrDir() "+path);
            assets = assetManager.list(path);
            if (assets.length == 0) {
                copyFile(path);
            } else {
                String fullPath =  TARGET_BASE_PATH + path;
                Log.i("tag", "path="+fullPath);
                File dir = new File(fullPath);
                if (!dir.exists() && !path.startsWith("images") && !path.startsWith("sounds") && !path.startsWith("webkit"))
                    if (!dir.mkdirs())
                        Log.i("tag", "could not create dir "+fullPath);
                for (int i = 0; i < assets.length; ++i) {
                    String p;
                    if (path.equals(""))
                        p = "";
                    else 
                        p = path + "/";
    
                    if (!path.startsWith("images") && !path.startsWith("sounds") && !path.startsWith("webkit"))
                        copyFileOrDir( p + 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;
        String newFileName = null;
        try {
            Log.i("tag", "copyFile() "+filename);
            in = assetManager.open(filename);
            if (filename.endsWith(".jpg")) // extension was added to avoid compression on APK file
                newFileName = TARGET_BASE_PATH + filename.substring(0, filename.length()-4);
            else
                newFileName = TARGET_BASE_PATH + 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", "Exception in copyFile() of "+newFileName);
            Log.e("tag", "Exception in copyFile() "+e.toString());
        }
    
    }
    

    编辑:更正了错位“;” 那是抛出一个系统性的“无法创建目录”的错误。

    链接地址: http://www.djcxy.com/p/93073.html

    上一篇: How to copy files from 'assets' folder to sdcard?

    下一篇: Android: Resize a large bitmap file to scaled output file