我刚刚开始为android开发。在我的应用程序中,我需要将资产文件夹中的项目复制到内部存储。
我在SO上搜索了很多,包括将其复制到外部存储的方法。 如何将“assets”文件夹中的文件复制到SD卡?
这就是我想要实现的目标: 我的内部存储中已存在一个目录,格式为 X>Y>Z。我需要将一个文件复制到 Y,将另一个文件复制到 Z。
任何人都可以帮我提供代码片段吗?我真的不知道如何继续下去。
使用
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);
}
}
我做了这样的事情。这允许您从 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");
}
}
}
这是我的 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)
}
}
尝试下面的代码
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);
}
}
我在 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()
}
}
}
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 中没有该方法,则调用此上下文/
希望有帮助
您可以使用 Envrionment#getDataDirectory 方法来实现。它将给出内部存储器的数据目录的路径。这通常是存储所有应用程序相关数据的地方。
或者,如果您想存储在根目录中,可以使用 Environment#getRootDirectory 方法。
如果您需要将资产中的任何文件复制到内部存储并且只需执行一次:
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;
}