Good day!
I have just started developing for 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.
How to copy files from 'assets' folder to sdcard?
This is what I want to achieve:
I have a directory already present in the internal storage as X>Y>Z. I need a file to be copied to Y and another to 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.
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);
}
}
This is my Kotlin solution with auto-closable streams to copy in internal app storage:
val copiedFile = File(context.filesDir, "copied_file.txt")
context.assets.open("original_file.txt").use { input ->
copiedFile.outputStream().use { output ->
input.copyTo(output, 1024)
}
}
My small solution on Kotlin, for copy data from assets to INTERNAL STORAGE
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();
}
}
}
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/
Hope it helps
You can use the Envrionment#getDataDirectory method for that. 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.
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;
}
Related
I generated a text file and tried to save it. It doesn't work only on android Q. On android 9 , 8 and 7 it works. When I check if file exists on android 10 it works but I don't it on device . I do this :
private void createFile(Context ctx, String fileName, String text) {
File filesDir = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
filesDir = ctx.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
}
assert filesDir != null;
if (!filesDir.exists()){
if(filesDir.mkdirs()){
}
}
File file = new File(filesDir, fileName + ".txt");
try {
if (!file.exists()) {
if (!file.createNewFile()) {
throw new IOException("Cant able to create file");
}
}
OutputStream os = new FileOutputStream(file);
byte[] data = text.getBytes();
os.write(data);
os.flush();
os.close();
Log.e("TAG", "File Path= " + file.toString());
if(file.exists()){
Log.e("d","d");
}
File fileTemp = new File(file.getPath());
FileInputStream notes_xml = new FileInputStream(fileTemp);
byte fileContent[] = new byte[(int)notes_xml.available()];
//The information will be content on the buffer.
notes_xml.read(fileContent);
String strContent = new String(fileContent);
Log.e("content",strContent);
notes_xml.close();
} catch (IOException e) {
e.printStackTrace();
}
}
I have copy many posible solutions from here and any unsuccess from me. I'm try to copy asset folder to storage data but always get error in logs after try to copy assets data
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;
Toast.makeText(this, ""+filename, Toast.LENGTH_LONG).show();
try {
in = assetManager.open(filename);
//File outFile = new File(Environment.getExternalStorageDirectory()+"/Android/data/"+getApplicationInfo().packageName+"/", filename);
File outFile = new File(Environment.getExternalStorageDirectory()+"/osmdroid/", filename);
out = new FileOutputStream(outFile);
//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);
}
}
Pleasy, Any know about this error??
06-23 18:06:06.316 10803-10803/com.restaurantesencuba.myapplication E/tag: Failed to copy asset file: images
java.io.FileNotFoundException: images
I got the exact same error, actually while debugging I found "images", "sounds" and "webkit", so seems to be you should just skip the non existing ones, because there is no other way to check if they exist:
AssetManager assetManager = context.getAssets();
String[] files;
try {
files = assetManager.list("");
} catch (IOException e) {
Log.e("tag", "Failed to get asset file list.", e);
return;
}
for(String filePath : files) {
try {
InputStream in = assetManager.open(filePath);
//do your work...
} catch (IOException ignored) { }
}
I have 2 files which are located deep in the android/data system, example of such a file below.
/storage/emulated/0/Android/data/mytest.com.test/files/Documents/Test/Bin/data.dat
I want to copy both of them to a location on the internal storage.
Now stackoverflow is a nice community which has a lot of examples and I therefore searched already for some examples how it is done but unfortunatly it is not working.
Logcat:
V/debug: Copy file failed. Source file missing.
I verified this but the files are definitely there, the destination directory is created but is empty.
Could anybody please assist me?
Main backup method:
public void backupFavorites() {
String folder1, folder2, folder3, folder4;
//Set target directory
String path = Utils.getDownloadDestination(this) + "/FavoritesBackup/Bin/";
File rootPath = new File(path);
if (!rootPath.exists())
rootPath.mkdirs();
//Prepare Sourcefile 1
folder1 = (rootPath + "/" + "data.dat");
File sdcardData = new File (this.getExternalFilesDir
("Documents"), "MyTestApp");
String pathdata = sdcardData.getPath() + "/Bin/data.dat";
File data = new File(pathdata);
//Prepare Sourcefile 2
folder2 = (rootPath + "/" + "trackerdata.dat");
File sdcardTracker = new File(this.getExternalFilesDir
("Documents"), "MyTestApp");
String pathtracker = sdcardTracker.getPath() + "/Bin/trackerdata.dat";
File tracker = new File(pathtracker);
if (trackerDataExists(this)) {
ArrayList<File> sourceFiles = new ArrayList<>();
sourceFiles.add(data);
sourceFiles.add(tracker);
ArrayList<String> destFiles = new ArrayList<>();
destFiles.add(folder1);
destFiles.add(folder2);
for (int i = 0; i < sourceFiles.size(); i++) {
for (int p = 0; p < destFiles.size(); p++) {
try {
copyFiles(sourceFiles.get(i), destFiles.get(p));
} catch (IOException e) {
e.printStackTrace();
}
}
}
Toast.makeText(this, "Backup created", Toast.LENGTH_SHORT).show();
}
}
Code which copies the files:
void copyFiles(File sourceLocation, String targtLocation) throws IOException {
if (sourceLocation.exists()) {
FileInputStream fin = null;
FileOutputStream fout = null;
Log.i("debug", "source " + sourceLocation);
Log.i("debug", "des " + targtLocation);
try {
fin = new FileInputStream(sourceLocation);
new File(String.valueOf(targtLocation)).delete();
fout = new FileOutputStream(targtLocation, false);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// Copy the bits from instream to outstream
byte[] buf = new byte[2048];
int len;
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fout);
BufferedInputStream bufferedInputStream = new BufferedInputStream(fin);
while ((len = bufferedInputStream.read(buf)) > 0) {
bufferedOutputStream.write(buf, 0, len);
}
fin.close();
bufferedOutputStream.close();
fout.close();
Log.e("debug", "Copy file successful.");
} else {
Log.v("debug", "Copy file failed. Source file missing.");
}
}
Code to get the download destination:
public static String getDownloadDestination(Context mCon) {
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(mCon);
return pref.getString("downloadFolder", MYDESTINATION.getAbsolutePath());
}
public static final File MYDESTINATION = new File(Environment.getExternalStorageDirectory(),
"Test");
I solved it myself. If anyone encounters the same issue, below is the working code.
public void backupFiles() {
if (DataExists(this)) {
ArrayList<String> sourceFiles = new ArrayList<>();
sourceFiles.add("codex.dat");
sourceFiles.add("ids.dat");
sourceFiles.add("data.dat");
for (int i = 0; i < sourceFiles.size(); i++) {
try {
copyFiles(sourceFiles.get(i));
} catch (IOException e) {
e.printStackTrace();
}
}
Toast.makeText(this, "Backup of FAVORITES created", Toast.LENGTH_SHORT).show();
}
}
public void copyFiles(String sourceLocation) throws IOException {
if (!sourceLocation.isEmpty()) {
FileInputStream fin = null;
FileOutputStream fout = null;
String path = Environment.getExternalStorageDirectory() + Utils.getDownloadDestination
(this) + "/TestBackup/Bin/";
File rootPath = new File(path);
if (!rootPath.exists())
rootPath.mkdirs();
File sdcardData = new File(this.getExternalFilesDir
("Documents"), "MyTest");
String pathdata = sdcardData.getPath() + "/Bin/" + sourceLocation;
File data = new File(pathdata);
Log.i("debug", "source " + pathData);
Log.i("debug", "des " + path + sourceLocation);
try {
fin = new FileInputStream(data);
File outFile = new File(path, sourceLocation);
fout = new FileOutputStream(outFile, true);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// Copy the bits from instream to outstream
byte[] buf = new byte[1024];
int len;
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fout);
BufferedInputStream bufferedInputStream = new BufferedInputStream(fin);
while ((len = bufferedInputStream.read(buf)) > 0) {
bufferedOutputStream.write(buf, 0, len);
}
fin.close();
bufferedOutputStream.close();
fout.close();
//Comment out to delete originals!
//data.delete();
Intent scanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
scanIntent.setData(Uri.parse(sourceLocation));
sendBroadcast(scanIntent);
Log.e("debug", "Copy file successful.");
} else {
Log.v("debug", "Copy file failed. Source file missing." + sourceLocation);
}
}
I'm using the code below to try and move my database file to my sdcard. I have no problems except that I get a redline under sd. Any ideas?
File data = Environment.getDataDirectory();
if (sd.canWrite()) {
String currentDBPath = "\\data\\application.package\\databases\\name";
String backupDBPath = "name";
File currentDB = new File(data, currentDBPath);
File backupDB = new File(sd, backupDBPath);
if (currentDB.exists()) {
FileChannel src;
try {
src = new FileInputStream(currentDB).getChannel();
FileChannel dst = new FileOutputStream(backupDB).getChannel();
try {
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
You can only use a variable if you create an instance of it:
Put this before your code:
File sd = Environment.getExternalStorageDirectory();
if you are using SQLite database try this:
public class _DBHelper extends SQLiteOpenHelper {
public boolean backUp() throws Exception
{
InputStream input = null;
OutputStream output = null;
try {
SQLiteDatabase db = this.getReadableDatabase();
String strSource = db.getPath();
String strDest = Utilities.getAppDocumentsFolder(_context) + "/"
+ DATABASE_NAME;
File fileDest = new File(strDest);
if (fileDest.exists())
{
fileDest.delete();
}
input = new FileInputStream(strSource);
output = new FileOutputStream(strDest);
byte[] buffer = new byte[1024];
int length;
while ((length = input.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
} catch (Exception e) {
throw e;
} finally
{
if (output != null)
{
output.flush();
output.close();
}
if (input != null)
{
input.close();
}
}
return true;
}
}
I'm using the code below to try and move my database file to my sdcard. I have no problems except that I get a redline under sd. Any ideas?
File data = Environment.getDataDirectory();
if (sd.canWrite()) {
String currentDBPath = "\\data\\application.package\\databases\\name";
String backupDBPath = "name";
File currentDB = new File(data, currentDBPath);
File backupDB = new File(sd, backupDBPath);
if (currentDB.exists()) {
FileChannel src;
try {
src = new FileInputStream(currentDB).getChannel();
FileChannel dst = new FileOutputStream(backupDB).getChannel();
try {
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
You can only use a variable if you create an instance of it:
Put this before your code:
File sd = Environment.getExternalStorageDirectory();
if you are using SQLite database try this:
public class _DBHelper extends SQLiteOpenHelper {
public boolean backUp() throws Exception
{
InputStream input = null;
OutputStream output = null;
try {
SQLiteDatabase db = this.getReadableDatabase();
String strSource = db.getPath();
String strDest = Utilities.getAppDocumentsFolder(_context) + "/"
+ DATABASE_NAME;
File fileDest = new File(strDest);
if (fileDest.exists())
{
fileDest.delete();
}
input = new FileInputStream(strSource);
output = new FileOutputStream(strDest);
byte[] buffer = new byte[1024];
int length;
while ((length = input.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
} catch (Exception e) {
throw e;
} finally
{
if (output != null)
{
output.flush();
output.close();
}
if (input != null)
{
input.close();
}
}
return true;
}
}