简体   繁体   English

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

[英]Android - Copy assets to internal storage

Good day!美好的一天!

I have just started developing for android.我刚刚开始为 android 开发。 In my app, I need to copy the items in my assets folder to the internal storage.在我的应用程序中,我需要将资产文件夹中的项目复制到内部存储。

I have searched a lot on SO including this which copies it to the external storage.我在 SO 上搜索了很多,包括将它复制到外部存储的这个。 How to copy files from 'assets' folder to sdcard? 如何将文件从“资产”文件夹复制到 SD 卡?

This is what I want to achieve: I have a directory already present in the internal storage as X>Y>Z.这就是我想要实现的目标:我在内部存储中已经有一个目录,如 X>Y>Z。 I need a file to be copied to Y and another to Z.我需要一个文件复制到 Y,另一个复制到 Z。

Can anyone help me out with a code snippet?任何人都可以帮助我解决代码片段吗? I really don't have any idea how to go on about this.我真的不知道该怎么做。

Sorry for my bad English.抱歉我的英语不好。

Thanks a lot.非常感谢。

Use使用

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

        File outFile = new File(out, Filename);

After Editing in your ref.在您的参考中编辑后。 Link Answer.链接答案。

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

I did something like this.我做了这样的事情。 This allows you to copy all the directory structure to copy from Android AssetManager.这允许您复制所有目录结构以从 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");
        }
    }
}

try this below code试试下面的代码

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

My small solution on Kotlin, for copy data from assets to INTERNAL STORAGE我在 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()
        }
    }
}

This is my Kotlin solution with auto-closable streams to copy in internal app storage:这是我的 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)
    }
}
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();
                 }

             }
         }

To add a file, call the addFilesToSystem("this_file_is_in_the_public_system", "this_file_is_in_the_assets_folder", context/ this context is if you do not have the method in the Activity /要添加文件,调用 addFilesToSystem("this_file_is_in_the_public_system", "this_file_is_in_the_assets_folder", context/这个上下文是如果你在Activity /

Hope it helps希望它有帮助

You can use the Envrionment#getDataDirectory method for that.您可以为此使用Envrionment#getDataDirectory方法。 It'll give the path of the data directory of the internal storage memory.它将给出内部存储器的数据目录的路径。 This is generally where all the app related data is stored.这通常是存储所有应用程序相关数据的地方。

Alternately, if you want to store in the root directory, you can use the Environment#getRootDirectory method for that.或者,如果要存储在根目录中,可以使用Environment#getRootDirectory方法。

If you need to copy any file from assets to the internal storage and do it only once:如果您需要将任何文件从资产复制到内部存储并且只执行一次:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM