Скопировать каталог из Активы в локальный каталог

Я пытаюсь использовать каталог, который у меня есть в моей папке с ресурсами, и получить к нему доступ в виде File . Возможно ли получить доступ к чему-либо в каталоге «Активы» в виде File ? Если нет, как я могу скопировать каталог из папки «Активы» в локальный каталог приложения?

Я бы скопировал такой файл:

  try { InputStream stream = this.getAssets().open("myFile"); OutputStream output = new BufferedOutputStream(new FileOutputStream(this.getFilesDir() + "/myNewFile")); byte data[] = new byte[1024]; int count; while((count = stream.read(data)) != -1) { output.write(data, 0, count); } output.flush(); output.close(); stream.close(); } catch(IOException e) { e.printStackTrace(); } 

Однако я не уверен, как это сделать для каталога.

Я бы предпочел не строить свою инфраструктуру вокруг чего-то, что не работает, так как мне скопировать каталог из Assets в локальный каталог или можно ли получить доступ к каталогу в моих активах в виде File ?

РЕДАКТИРОВАТЬ

Вот как я решил это для моего собственного проекта:

 InputStream stream = null; OutputStream output = null; for(String fileName : this.getAssets().list("demopass")) { stream = this.getAssets().open("directoryName/" + fileName); output = new BufferedOutputStream(new FileOutputStream(this.getFilesDir() + "/newDirectory/" + fileName)); byte data[] = new byte[1024]; int count; while((count = stream.read(data)) != -1) { output.write(data, 0, count); } output.flush(); output.close(); stream.close(); stream = null; output = null; } 

Как было предложено dmaxi в комментарии выше, вы можете использовать его ссылку, используя этот код:

  void displayFiles (AssetManager mgr, String path) { try { String list[] = mgr.list(path); if (list != null) for (int i=0; i<list.length; ++i) { Log.v("Assets:", path +"/"+ list[i]); displayFiles(mgr, path + "/" + list[i]); } } catch (IOException e) { Log.v("List error:", "can't list" + path); } } 

Я взял его по этой ссылке . Возможно, вы можете комбинировать этот код с прецедентным.

EDIT: см. Также AssetManager .

 private void copyFolder(String name) { // "Name" is the name of your folder! AssetManager assetManager = getAssets(); String[] files = null; String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state)) { // We can read and write the media // Checking file on assets subfolder try { files = assetManager.list(name); } catch (IOException e) { Log.e("ERROR", "Failed to get asset file list.", e); } // Analyzing all file on assets subfolder for(String filename : files) { InputStream in = null; OutputStream out = null; // First: checking if there is already a target folder File folder = new File(Environment.getExternalStorageDirectory() + "/yourTargetFolder/" + name); boolean success = true; if (!folder.exists()) { success = folder.mkdir(); } if (success) { // Moving all the files on external SD try { in = assetManager.open(name + "/" +filename); out = new FileOutputStream(Environment.getExternalStorageDirectory() + "/yourTargetFolder/" + name + "/" + filename); Log.i("WEBVIEW", Environment.getExternalStorageDirectory() + "/yourTargetFolder/" + name + "/" + filename); copyFile(in, out); in.close(); in = null; out.flush(); out.close(); out = null; } catch(IOException e) { Log.e("ERROR", "Failed to copy asset file: " + filename, e); } finally { // Edit 3 (after MMs comment) in.close(); in = null; out.flush(); out.close(); out = null; } } else { // Do something else on failure } } } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { // We can only read the media } else { // Something else is wrong. It may be one of many other states, but all we need // is to know is we can neither read nor write } } // Method used by copyAssets() on purpose to copy a file. 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); } } 

EDIT 2: я добавил пример выше: этот фрагмент кода копирует только определенную папку из активов, на SD-карту. Дайте мне знать, если это сработает!

Вы можете использовать следующий метод для копирования папки вашего ресурса в местоположение на SD-карте. Из вашего метода вызова просто вызовите moveAssetToStorageDir ("") для перемещения всей папки с данными. В случае подпапок вы можете указать относительный путь в папке с ресурсами.

 public void moveAssetToStorageDir(String path){ File file = getExternalFilesDir(null); String rootPath = file.getPath() + "/" + path; try{ String [] paths = getAssets().list(path); for(int i=0; i<paths.length; i++){ if(paths[i].indexOf(".")==-1){ File dir = new File(rootPath + paths[i]); dir.mkdir(); moveAssetToStorageDir(paths[i]); }else { File dest = null; InputStream in = null; if(path.length() == 0) { dest = new File(rootPath + paths[i]); in = getAssets().open(paths[i]); }else{ dest = new File(rootPath + "/" + paths[i]); in = getAssets().open(path + "/" + paths[i]); } dest.createNewFile(); FileOutputStream out = new FileOutputStream(dest); byte [] buff = new byte[in.available()]; in.read(buff); out.write(buff); out.close(); in.close(); } } }catch (Exception exp){ exp.printStackTrace(); } } 

Перемещение произвольной папки каталогов и файлов из Assets

Дело в том, что … Активы особенные. Вы не можете обернуть его в объект File и спросить isDirectory() и вы не можете передать эти активы в NDK. Так что лучше их обернуть и переместить в каталог кеша или на SDCard, поэтому вы здесь.

Я видел много ответов SO, которые включают некоторую версию прокатки по массиву строк fileOrDirectoryName, а затем создание каталогов, за которыми следует рекурсивный вызов и копирование отдельных файлов. Это приводит к созданию папки или файла, и вы не можете указать из актива, который у вас есть.

Сделайте его Zip-файлом

Моя рекомендация состоит в том, чтобы взять каждый произвольный набор активов, которые вы хотите отправить в SDCard или в папку внутреннего кэша, и закрепить его. Проблема структурирована таким образом, что более совместима с концепцией «Активы».

 AssetManager assetManager = context.getAssets(); String fullAssetPath = fromAssetPath + "/" + zipFilename; String toPath = "/wherever/I/want"; try { InputStream inputStream = assetManager.open(fullAssetPath); ZipInputStream zipInputStream = new ZipInputStream(new BufferedInputStream(inputStream)); ZipEntry zipEntry; byte[] buffer = new byte[8192]; while ((zipEntry = zipInputStream.getNextEntry()) != null) { String fileOrDirectory = zipEntry.getName(); Uri.Builder builder = new Uri.Builder(); builder.scheme("file"); builder.appendPath(toPath); builder.appendPath(fileOrDirectory); String fullToPath = builder.build().getPath(); if (zipEntry.isDirectory()) { File directory = new File(fullToPath); directory.mkdirs(); continue; } FileOutputStream fileOutputStream = new FileOutputStream(fullToPath); while ((count = zipInputStream.read(buffer)) != -1) { fileOutputStream.write(buffer, 0, count); } fileOutputStream.close(); zipInputStream.closeEntry(); } zipInputStream.close(); } catch (IOException e) { Log.e(TAG, e.getLocalizedMessage()); } 

Небольшое примечание о размерах буфера

Я видел много примеров, связанных с очень маленькими размерами буфера, например 1024. Если вы просто не хотите тратить время, не стесняйтесь использовать более крупные размеры буфера. Даже мой выбор 8192, вероятно, невелик на современном оборудовании.

Избегайте строгих путей

Обратите внимание на использование Uri.Builder для создания пути. Я предпочитаю этот стиль построения пути над directory + "/" + file . Тогда вы находитесь в бизнесе, ради согласованности, избегая назначения String d = "myDirectory/" или String f = "/file.txt" и других подобных хакерских взломов.

Intereting Posts
Любой совместный инструмент / веб-сайт для локализации приложения для Android? Отмена камеры после выбора намерения отменена Что представляет собой Android-эквивалент приложения для приложения UICatalog для iOS / iPhone? Как динамически менять цвет кнопок и текста на андроиде Правильно определить тип устройства Android Невозможно понять, как получить ширину / высоту представления / макета Glide не может загружать файл из внутреннего хранилища Добавление аргументов в AndroidAnnotation с добавлением bean-компонентов Вызывается метод onSaveInstanceState (Bundle) после onPause ()? Android: GoogleAuthUtil.getToken – где должен быть объект учетной записи? Android: Listview не показывает никаких результатов Андроидный эмулятор в плагине ADT не работает Как удалить лишнее пространство из меню Почему мое приложение в списке приложений не открывает файл txt? Как установить выходное изображение, используйте com.android.camera.action.CROP