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 have two node on production environment. I have placed pdf files at one server and want to read it from both server. when am calling 'file' method directly pdf get displayed in browser but when i call 'pdfFiles' nothing is displayed in browser.
public Resolution file(){
try {
final HttpServletRequest request = getContext().getRequest();
String fileName = (String) request.getParameter("file");
File file = new File("pdf file directory ex /root/pdffiles/" + fileName);
getContext().getResponse().setContentType("application/pdf");
getContext().getResponse().addHeader("Content-Disposition",
"inline; filename=" + fileName);
FileInputStream streamIn = new FileInputStream(file);
BufferedInputStream buf = new BufferedInputStream(streamIn);
int readBytes = 0;
ServletOutputStream stream = getContext().getResponse().getOutputStream();
// read from the file; write to the ServletOutputStream
while ((readBytes = buf.read()) != -1)
stream.write(readBytes);
} catch (Exception exc) {
LOGGER.logError("reports", exc);
}
return null;
}
public Resolution pdfFile() {
final HttpServletRequest request = getContext().getRequest();
final HttpClient client = new HttpClient();
try {
String fileName = (String) request.getParameter("file");
final String url = "http://" + serverNameNode1 //having pdf files
+ "/test/sm.action?reports&file=" + fileName;
final PostMethod method = new PostMethod(url);
try {
client.executeMethod(method);
} finally {
method.releaseConnection();
}
} catch (final Exception e) {
LOGGER.logError("pdfReports", "error occured2 " + e.getMessage());
}
return null;
}
Included below part of code after 'client.executeMethod(method);' in 'pdfFile()' method and it works for me.
buf = new BufferedInputStream(method.getResponseBodyAsStream());
int readBytes = 0;
stream = getContext().getResponse().getOutputStream();
// write to the ServletOutputStream
while ((readBytes = buf.read()) != -1)
stream.write(readBytes);
I am developing an application that takes an XML file and an attachment to be sent to the following path. This path is for a fax appliance.
I keep getting this error message:
Problem processing drop file "\co1-aux01prd01.tampa.healthe\Fax_Drop\Outbox\FaxDropSample1.xml": Illegal characters in path.
The XML file and the attachment are both being created but not processed.
public class TestSender {
public static void main(String[] args) {
String outBox = "\\\\faxaux\\Fax_Drop\\Outbox";
String filename = "FaxDrop" + ".xml";
String filepath = outBox + "\\" + filename;
Writer writer = null;
try {
BufferedImage image;
URL url = new URL("http://colsolgrp.com/phone/jpg/fax8.jpg");
image = ImageIO.read(url);
//File newImage = new File("\\\\faxaux\\Fax_Drop\\Outbox\\AttachmentFolder\\attachment.jpg");
File newImage = new File("\\\\faxaux\\Fax_Drop\\Outbox\\FaxDrop\\FaxDropImage.jpg");
newImage.mkdirs();
newImage.createNewFile();
ImageIO.write(image, "jpg",newImage);
System.out.println("File has been written");
}
catch(Exception e) {
System.out.println("Could not create file");
}
try {
File f = new File(filepath);
f.createNewFile();
FileOutputStream fileOutputStream = new FileOutputStream(f);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream);
writer = new BufferedWriter(outputStreamWriter);
// Create XML file here
}
catch (Throwable ex) {
ex.printStackTrace();
}
finally {
try {
writer.close();
}
catch (Exception ex) {
// Do nothing.
}
}
System.out.println("Success");
Try this:
URI u = new URI(URLEncoder.encode("\\co1-aux01prd01.tampa.healthe\Fax_Drop\Outbox\FaxDropSample1.xml"));
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;
}
I am creating a application that will download a lot of files from my own web server. But idk why it is not working. It dont have any response..
Here is some part of my code
Downloader.class
private Proxy proxy = Proxy.NO_PROXY;
public void downloadLibrary()
{
System.out.println("Start downloading libraries from server...");
try
{
URL resourceUrl = new URL("http://www.example.com/libraries.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(resourceUrl.openConnection(proxy).getInputStream());
NodeList nodeLst = doc.getElementsByTagName("Contents");
for (int i = 0; i < nodeLst.getLength(); i++)
{
Node node = nodeLst.item(i);
if (node.getNodeType() == 1)
{
Element element = (Element)node;
String key = element.getElementsByTagName("Key").item(0).getChildNodes().item(0).getNodeValue();
File f = new File(launcher.getWorkingDirectory(), key);
downloadFile("http://www.example.com/" + key, f, "libraries");
}
}
}
catch(Exception e)
{
System.out.println("Error was found when trying to download libraries file " + e);
}
}
public void downloadFile(final String url, final File path, final String fileName)
{
SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>()
{
#Override
protected Void doInBackground() throws Exception
{
launcher.println("Downloading file " + fileName + "...");
try
{
URL fileURL = new URL(url);
ReadableByteChannel rbc = Channels.newChannel(fileURL.openStream());
FileOutputStream fos = new FileOutputStream(path);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
}
catch(Exception e)
{
System.out.println("Cannot download file : " + fileName + " " + e);
}
return null;
}
#Override
public void done()
{
System.out.println(fileName + " had downloaded sucessfully");
}
};
worker.execute();
}
Here is some part of my xml file(libraries.xml)
<Key>libraries/org/lwjgl/lwjgl/lwjgl/2.9.0/lwjgl-2.9.0.jar</Key>
My idea is, my application will read the XML file. Then it will download file from the server and save to computer. For example, my application download http://www.example.com/libraries/org/lwjgl/lwjgl/lwjgl/2.9.0/lwjgl-2.9.0.jar then it will save to C://WorkingDir/libraries/org/lwjgl/lwjgl/lwjgl/2.9.0/lwjgl-2.9.0.jar
There is ton of <Key></Key> in my XML file and i have to download all of it.
Is that any code wrong? Thanks for helping.
Try consuming the connection directly through a reader of some sort to a String first, then you can manipulate that however you need.
package come.somecompany.somepackage.utils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
public class WebUtils {
/**
* Gets the HTML value of a website and
* returns as a string value.
*
* #param website website url to get.
* #param ssl True if website is SSL.
* #param useragent Specified User-Agent (empty string "" means use system default).
* #return String value of website.
*/
public String getHTML(String website, boolean ssl, String useragent) {
String html = "";
String temp;
String prefix;
if (ssl) {
prefix = "https://";
} else {
prefix = "http://";
}
try {
URL url = new URL(prefix + website);
URLConnection con = url.openConnection();
if (!(useragent.equalsIgnoreCase(""))) {
con.setRequestProperty("User-Agent", useragent);
}
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
while((temp = in.readLine()) != null) {
html += temp + "\n";
}
in.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return html;
}
}
Also, it sort of looks like you are attempting to parse HTML using an XML pattern... which may give you difficulties. You could try out JSoup - it's a java HTML parser, and works pretty well and is easy: http://jsoup.org/
It may help with consuming documents from your website without needing to build your own downloader too.
UPDATE --
Try reading into a BufferedReader, perhaps your program isn't receiving the full document, buffered reader may help.
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
So with your first method, something like:
public void downloadLibrary()
{
System.out.println("Start downloading libraries from server...");
try
{
URL resourceUrl = new URL("http://www.example.com/libraries.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
// change here
URLConnection con = resourceUrl.openConnection();
BufferedReader bfr = new BufferedReader(new InputStreamReader(con.getInputStream()));
String tempDoc = "";
String tempStr;
while (tempStr = bfr.readLine()) != null) {
tempDoc += tempStr + System.getProperty("line.separator");
}
Document doc = db.parse(tempDoc);
NodeList nodeLst = doc.getElementsByTagName("Contents");
for (int i = 0; i < nodeLst.getLength(); i++)
{
Node node = nodeLst.item(i);
if (node.getNodeType() == 1)
{
Element element = (Element)node;
String key = element.getElementsByTagName("Key").item(0).getChildNodes().item(0).getNodeValue();
File f = new File(launcher.getWorkingDirectory(), key);
downloadFile("http://www.example.com/" + key, f, "libraries");
}
}
}
catch(Exception e)
{
System.out.println("Error was found when trying to download libraries file " + e);
}
}