如何从“资产”复制文件文件夹到SD卡?
我的 assets
文件夹中有一些文件。我需要将它们全部复制到 /sdcard/folder 文件夹中。我想在线程内执行此操作。我该怎么做?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
我的 assets
文件夹中有一些文件。我需要将它们全部复制到 /sdcard/folder 文件夹中。我想在线程内执行此操作。我该怎么做?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(23)
如果其他人也遇到同样的问题,这就是我的做法
参考:使用以下命令移动文件Java
If anyone else is having the same problem, this is how I did it
Reference : Move file using Java
根据您的解决方案,我做了一些自己的事情来允许子文件夹。有人可能会发现这很有帮助
......
:
Based on your solution, I did something of my own to allow subfolders. Someone might find this helpful:
...
...
由于某些错误,上述解决方案不起作用:
这是代码(我留下了日志语句,但您现在可以删除它们):
编辑:更正了错误的“;”这引发了系统性的“无法创建目录”错误。
The solution above did not work due to some errors:
Here is the code (I left the Log statements but you can drop them now):
EDIT: Corrected a misplaced ";" that was throwing a systematic "could not create dir" error.
我知道这个问题已经得到解答,但我有一种稍微更优雅的方法来从资产目录复制到 SD 卡上的文件。它不需要“for”循环,而是使用文件流和通道来完成工作。
(注意)如果使用任何类型的压缩文件,APK,PDF,...您可能需要在插入资产之前重命名文件扩展名,然后在将其复制到 SD 卡后重命名)
复制文件而无需循环遍历它。
I know this has been answered but I have a slightly more elegant way to copy from asset directory to a file on the sdcard. It requires no "for" loop but instead uses File Streams and Channels to do the work.
(Note) If using any type of compressed file, APK, PDF, ... you may want to rename the file extension before inserting into asset and then rename once you copy it to SDcard)
A way to copy a file without having to loop through it.
这在 Kotlin 中是一种简洁的方式。
This would be concise way in Kotlin.
试试这个,它更简单,这会对你有帮助:
try out this it is much simpler ,this will help u:
这是当前 Android 设备的清理版本,功能方法设计,以便您可以将其复制到 AssetsHelper 类,例如;)
Here is a cleaned up version for current Android devices, functional method design so that you can copy it to an AssetsHelper class e.g ;)
修改了@DannyA SO的答案
< strong>准备工作
src/main/assets
中的添加名为
fold
的文件夹用法
在外部目录中查找折叠资源中的所有文件和目录
Modified this SO answer by @DannyA
Preparations
in
src/main/assets
add folder with name
fold
Usage
In to the external directory find all files and directories that are within the fold assets
将资产中的所有文件和目录复制到您的文件夹!
为了更好地复制,请使用 apache commons io
//这是复制的主要方法
Copy all files and directories from assets to your folder!
for copying better use apache commons io
//THIS IS MAIN METHOD FOR COPY
基于 Rohith Nandakumar 的解决方案,我自己做了一些事情,从资产的子文件夹(即“assets/MyFolder”)复制文件。另外,我正在检查该文件是否已存在于 SD 卡中,然后再尝试再次复制。
Based on Rohith Nandakumar's solution, I did something of my own to copy files from a subfolder of assets (i.e. "assets/MyFolder"). Also, I'm checking if the file already exists in sdcard before trying to copy again.
您可以使用 Kotlin 只需几个步骤即可完成此操作,这里我仅将少数文件而不是所有文件从资产复制到我的应用程序文件目录。
这是扩展函数,
LOGCAT
You can do it in few steps using Kotlin, Here I am copying only few files instead of all from asstes to my apps files directory.
And here is the extension function,
LOGCAT
根据 Yoram Cohen 的回答,这是一个支持非静态目标目录的版本。
使用
copyFileOrDir(getDataDir(), "")
调用以写入内部应用存储文件夹 /data/data/pkg_name/避免复制“图像”等虚假资产文件夹
Based on Yoram Cohen answer, here is a version that supports non static target directory.
Invoque with
copyFileOrDir(getDataDir(), "")
to write to internal app storage folder /data/data/pkg_name/Avoids copying "images" etc fake asset folders like
使用这个问题的答案中的一些概念,我编写了一个名为
AssetCopier
的类,以使复制/assets/
变得简单。它可以在 github 上找到,并且可以通过 jitpack.io:请参阅 https://github。 com/flipagram/android-assetcopier 了解更多详细信息。
Using some of the concepts in the answers to this question, I wrote up a class called
AssetCopier
to make copying/assets/
simple. It's available on github and can be accessed with jitpack.io:See https://github.com/flipagram/android-assetcopier for more details.
基本上有两种方法可以做到这一点。
首先,您可以使用 AssetManager。打开并按照Rohith Nandakumar所述并迭代输入流。
其次,您可以使用 AssetManager。 openFd,它允许您使用 FileChannel (其中有 transferTo 和 transferFrom 方法),这样你就不用自己循环输入流了。
我在这里描述一下 openFd 方法。
压缩
首先你需要确保文件以未压缩的方式存储。打包系统可能会选择压缩任何扩展名未标记为“noCompress”的文件,并且压缩文件无法进行内存映射,因此您必须依赖“AssetManager”。在这种情况下.open。
您可以向文件添加“.mp3”扩展名以阻止其被压缩,但正确的解决方案是修改您的 app/build.gradle 文件并添加以下行(以禁用压缩PDF 文件)
文件打包
请注意,打包程序仍然可以将多个文件打包为一个文件,因此您不能只读取 AssetManager 提供给您的整个文件。您需要询问AssetFileDescriptor您需要哪些部分。
查找打包文件的正确部分
一旦确保文件以未压缩的方式存储,您就可以使用 AssetManager.openFd 方法获取 AssetFileDescriptor,可用于获取FileInputStream(与AssetManager.open不同) ,它返回一个包含FileChannel的InputStream)。它还包含起始偏移量 (getStartOffset) 和 大小 (getLength),其中您需要获取文件的正确部分。
实现
下面给出了一个示例实现:
这个答案基于 JPM 的答案。
There are essentially two ways to do this.
First, you can use AssetManager.open and, as described by Rohith Nandakumar and iterate over the inputstream.
Second, you can use AssetManager.openFd, which allows you to use a FileChannel (which has the transferTo and transferFrom methods), so you don't have to loop over the input stream yourself.
I will describe the openFd method here.
Compression
First you need to ensure that the file is stored uncompressed. The packaging system may choose to compress any file with an extension that is not marked as noCompress, and compressed files cannot be memory mapped, so you will have to rely on AssetManager.open in that case.
You can add a '.mp3' extension to your file to stop it from being compressed, but the proper solution is to modify your app/build.gradle file and add the following lines (to disable compression of PDF files)
File packing
Note that the packager can still pack multiple files into one, so you can't just read the whole file the AssetManager gives you. You need to to ask the AssetFileDescriptor which parts you need.
Finding the correct part of the packed file
Once you've ensured your file is stored uncompressed, you can use the AssetManager.openFd method to obtain an AssetFileDescriptor, which can be used to obtain a FileInputStream (unlike AssetManager.open, which returns an InputStream) that contains a FileChannel. It also contains the starting offset (getStartOffset) and size (getLength), which you need to obtain the correct part of the file.
Implementation
An example implementation is given below:
This answer is based on JPM's answer.
更改部分代码如下:
前面的示例适用于 Pdfs,如果是示例 .txt
change parts of code like these:
the before example is for Pdfs, in case of to example .txt
大家好,我做了这样的事情。
用于要复制的第 N 个深度复制文件夹和文件。
它允许您复制所有目录结构以从 Android AssetManager 复制:)
最后创建一个异步任务:
从您的活动中调用它:
Hi Guys I Did Something like this.
For N-th Depth Copy Folder and Files to copy.
Which Allows you to copy all the directory structure to copy from Android AssetManager :)
In the end Create a Asynctask:
call it From your activity:
对上述答案进行轻微修改,以递归方式复制文件夹并适应自定义目标。
Slight modification of above answer to copy a folder recursively and to accommodate custom destination.
对于要更新到 Kotlin 的用户:
按照此步骤避免
FileUriExposedExceptions
,假设用户已授予
WRITE_EXTERNAL_STORAGE
权限,并且您的文件位于assets/pdfs/mypdf.pdf
中。For those who are updating to Kotlin:
Following this steps to avoid
FileUriExposedExceptions
,supposing user has granted
WRITE_EXTERNAL_STORAGE
permission and your file is inassets/pdfs/mypdf.pdf
.这是我的个性化文本提取器类,希望有用。
要使用它,您需要经过训练的数据文件。您可以从此链接下载trainddata文件。
下载所需的训练数据文件后,您需要在 Android 项目中创建一个名为 asset 的 Android 资源目录。在新创建的资产文件夹中,您需要创建一个名为“tessdata”的常规目录,您可以在其中放置训练数据文件。
最后,您必须在 MainActivity 中初始化“TextExtractor”类。
第一个参数是上下文,第二个参数是刚刚创建的目录名称,最后一个参数是刚刚下载的训练数据的语言。
要提取文本,您必须调用“extractText”方法:
请注意,extractText 需要 BitMap 图像才能工作!
您可以使用以下行从可绘制文件创建位图图像:
如果您需要更多支持,我建议您遵循这个有用的指南:https://github.com/SamVanRoy/Android_OCR_App
That is my personalized text extractor class, hope that will be usefull.
To use that you need traineddata file. You can download trainddata file from this link.
Once you’ve downloaded the traineddata file you want, you need to make an Android Resource directory named assets in your android project. In the newly created assets folder, you need to create a regular directory named “tessdata” where you can place your traineddata files.
Finally you have to init the "TextExtractor" class in your MainActivity.
First parameter is the context, the second one is the name of directory just created and the last one is the language of traineddata just downloaded.
To extract text you have to call the "extractText" method:
Note that extractText need a BitMap image to work!!
You can create a BitMap image from your drawable file with this line:
If you need more support, I suggest you to follow this usefull guide: https://github.com/SamVanRoy/Android_OCR_App
在 Kotlin 中,只需一行即可完成!
将扩展 fun 添加到 InputStream
然后使用它
MainActivity.kt
In Kotlin it can be done with one line!
Add extension fun to InputStream
then use it
MainActivity.kt
这是迄今为止我在互联网上找到的最好的解决方案。
我使用了以下链接 https://gist.github.com/mhasby/026f02b33fcc4207b302a60645f6e217 ,
但它有一个错误,我修复了它,然后它就像一个魅力。
这是我的代码。您可以轻松使用它,因为它是一个独立的 java 类。
正如您所看到的,只需在具有活动的 java 类中创建一个 CopyAssets 实例即可。现在这部分很重要,据我在互联网上的测试和研究,
如果类没有 Activity,则无法使用 AssetManager
。和java类的上下文有关系。现在,c.copyAssets(getApplicationContext()) 是访问该方法的简单方法,其中 c 是 CopyAssets 类的实例。
根据我的要求,我允许程序将
asset
文件夹中的所有资源文件复制到我的内部目录的/www/resources/
中。您可以根据您的使用轻松找到需要更改目录的部分。
如果您需要任何帮助,请随时联系我。
This is by far the best solution I have been able to find on the internet.
I've used the following link https://gist.github.com/mhasby/026f02b33fcc4207b302a60645f6e217,
but it had a single error which I fixed and then it works like a charm.
Here's my code. You can easily use it as it is an independent java class.
As you can see, just create an instance of
CopyAssets
in your java class which has an activity. Now this part is important, as far as my testing and researching on the internet,You cannot use AssetManager if the class has no activity
. It has something to do with the context of the java class.Now, the
c.copyAssets(getApplicationContext())
is an easy way to access the method, wherec
is and instance ofCopyAssets
class.As per my requirement, I allowed the program to copy all my resource files inside the
asset
folder to the/www/resources/
of my internal directory.You can easily find out the part where you need to make changes to the directory as per your use.
Feel free to ping me if you need any help.
您还可以使用Guava的
ByteStream
将文件从assets文件夹复制到SD卡。这是我最终得到的解决方案,它将文件从资产文件夹递归复制到 SD 卡:You can also use Guava's
ByteStream
to copy the files from the assets folder to the SD card. This is the solution I ended up with which copies files recursively from the assets folder to the SD card:使用 AssetManager,它允许读取资源中的文件。然后使用常规 Java IO 将文件写入 sdcard。
谷歌是你的朋友,搜索一个例子。
Use AssetManager, it allows to read the files in the assets. Then use regular Java IO to write the files to sdcard.
Google is your friend, search for an example.