Android - 将资产复制到内部存储

问题描述 投票:0回答:8

我刚刚开始为android开发。在我的应用程序中,我需要将资产文件夹中的项目复制到内部存储。

我在SO上搜索了很多,包括将其复制到外部存储的方法。 如何将“assets”文件夹中的文件复制到SD卡?

这就是我想要实现的目标: 我的内部存储中已存在一个目录,格式为 X>Y>Z。我需要将一个文件复制到 Y,将另一个文件复制到 Z。

任何人都可以帮我提供代码片段吗?我真的不知道如何继续下去。

java android
8个回答
30
投票

使用

 String out= Environment.getExternalStorageDirectory().getAbsolutePath() + "/X/Y/Z/" ; 

        File outFile = new File(out, Filename);

在参考文献中编辑后。链接答案。

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

      String outDir = Environment.getExternalStorageDirectory().getAbsolutePath() + "/X/Y/Z/" ; 

      File outFile = new File(outDir, 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);
     }
   }

20
投票

我做了这样的事情。这允许您从 Android AssetManager 复制所有要复制的目录结构。

public String copyDirorfileFromAssetManager(String arg_assetDir, String arg_destinationDir) throws IOException
{
    File sd_path = Environment.getExternalStorageDirectory(); 
    String dest_dir_path = sd_path + addLeadingSlash(arg_destinationDir);
    File dest_dir = new File(dest_dir_path);

    createDir(dest_dir);

    AssetManager asset_manager = getApplicationContext().getAssets();
    String[] files = asset_manager.list(arg_assetDir);

    for (int i = 0; i < files.length; i++)
    {

        String abs_asset_file_path = addTrailingSlash(arg_assetDir) + files[i];
        String sub_files[] = asset_manager.list(abs_asset_file_path);

        if (sub_files.length == 0)
        {
            // It is a file
            String dest_file_path = addTrailingSlash(dest_dir_path) + files[i];
            copyAssetFile(abs_asset_file_path, dest_file_path);
        } else
        {
            // It is a sub directory
            copyDirorfileFromAssetManager(abs_asset_file_path, addTrailingSlash(arg_destinationDir) + files[i]);
        }
    }

    return dest_dir_path;
}


public void copyAssetFile(String assetFilePath, String destinationFilePath) throws IOException
{
    InputStream in = getApplicationContext().getAssets().open(assetFilePath);
    OutputStream out = new FileOutputStream(destinationFilePath);

    byte[] buf = new byte[1024];
    int len;
    while ((len = in.read(buf)) > 0)
        out.write(buf, 0, len);
    in.close();
    out.close();
}

public String addTrailingSlash(String path)
{
    if (path.charAt(path.length() - 1) != '/')
    {
        path += "/";
    }
    return path;
}

public String addLeadingSlash(String path)
{
    if (path.charAt(0) != '/')
    {
        path = "/" + path;
    }
    return path;
}

public void createDir(File dir) throws IOException
{
    if (dir.exists())
    {
        if (!dir.isDirectory())
        {
            throw new IOException("Can't create directory, a file is in the way");
        }
    } else
    {
        dir.mkdirs();
        if (!dir.isDirectory())
        {
            throw new IOException("Unable to create directory");
        }
    }
}

14
投票

这是我的 Kotlin 解决方案,具有可自动关闭的流以复制到内部应用程序存储中:

val copiedFile = File(context.filesDir, "copied_file.txt")
context.assets.open("original_file.txt").use { input ->
    copiedFile.outputStream().use { output ->
        input.copyTo(output, 1024)
    }
}

10
投票

尝试下面的代码

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

7
投票

我在 Kotlin 上的小解决方案,用于将数据从资产复制到内部存储

fun copy() {
    val bufferSize = 1024
    val assetManager = context.assets
    val assetFiles = assetManager.list("")

    assetFiles.forEach {
        val inputStream = assetManager.open(it)
        val outputStream = FileOutputStream(File(context.filesDir, it))

        try {
            inputStream.copyTo(outputStream, bufferSize)
        } finally {
            inputStream.close()
            outputStream.flush()
            outputStream.close()
        }
    }
}

1
投票
public void addFilesToSystem(String sysName, String intFil, Context c){
             //sysName is the name of the file we have in the android os
             //intFil is the name of the internal file



             file = new File(path, sysName + ".txt");

             if(!file.exists()){
                 path.mkdirs();

                 try {

                     AssetManager am = c.getAssets();

                     InputStream is = am.open(intFil);
                     OutputStream os = new FileOutputStream(file);
                     byte[] data = new byte[is.available()];
                     is.read(data);
                     os.write(data);
                     is.close();
                     os.close();

                     Toast t = Toast.makeText(c, "Making file: " + file.getName() + ". One time action", Toast.LENGTH_LONG);
                     t.show();

                     //Update files for the user to use
                     MediaScannerConnection.scanFile(c,
                             new String[] {file.toString()},
                             null, 
                             new MediaScannerConnection.OnScanCompletedListener() {

                         public void onScanCompleted(String path, Uri uri) {
                             // TODO Auto-generated method stub

                         }
                     });



                 }  catch (IOException e) {
                     Toast t = Toast.makeText(c, "Error: " + e.toString() + ". One time action", Toast.LENGTH_LONG);
                     t.show();
                     e.printStackTrace();
                 }

             }
         }

要添加文件,请调用 addFilesToSystem("this_file_is_in_the_public_system", "this_file_is_in_the_assets_folder", context/如果您在 Activity 中没有该方法,则调用此上下文/

希望有帮助


0
投票

您可以使用 Envrionment#getDataDirectory 方法来实现。它将给出内部存储器的数据目录的路径。这通常是存储所有应用程序相关数据的地方。

或者,如果您想存储在根目录中,可以使用 Environment#getRootDirectory 方法。


0
投票

如果您需要将资产中的任何文件复制到内部存储并且只需执行一次:

public void writeFileToStorage() {
        Logger.d(TAG, ">> writeFileToStorage");

        AssetManager assetManager = mContext.getAssets();
        if (new File(getFilePath()).exists()) {
            Logger.d(TAG, "File exists, do nothing");
            Logger.d(TAG, "<< writeFileToStorage");
            return;
        }

        try (InputStream input = assetManager.open(FILE_NAME);
             OutputStream output = new FileOutputStream(getFilePath())) {

            Logger.d(TAG, "File does not exist, write it");

            byte[] buffer = new byte[input.available()];
            int length;
            while ((length = input.read(buffer)) != -1) {
                output.write(buffer, 0, length);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
            Logger.e(TAG, "File is not found");
        } catch (IOException e) {
            e.printStackTrace();
            Logger.d(TAG, "Error while writing the file");
        }

        Logger.d(TAG, "<< writeFileToStorage");
    }

public String getFilePath() {
    String filePath = mContext.getFilesDir() + "/" + FILE_NAME;
    Logger.d(TAG, "File path: " + filePath);
    return filePath;
}
© www.soinside.com 2019 - 2024. All rights reserved.