Trouble copying file in Android - java

My problem is not How to make a copy of a File in Android, My problem is why it fails to make a copy.
After my app downloads a file am trying to copy it to another folder (The end user can save the file in several folder, that why i download once and copy to the rest). I do have the origin file path like:
/storage/emulated/0/MyAppFolder/FolderCreatedByUser1/theFile.pdf
And am trying to copy it to
/storage/emulated/0/MyAppFolder/FolderCreatedByUser2/
With this code (Code improved by Robert Nekic):
public static boolean copyFile(File src, File[] dst) {
boolean result = true;
if (src.exists()) {
String srcName = src.getName();
for (File file : dst) {
String to = file.getPath();
try {
File destination = new File(to, srcName);
if (destination.createNewFile()) {
FileChannel srcChnl = new FileInputStream(src).getChannel();
FileChannel dstChnl = new FileOutputStream(destination).getChannel();
dstChnl.transferFrom(srcChnl, 0, srcChnl.size());
srcChnl.close();
dstChnl.close();
} else {
result = false;
System.out.println("Unable to create destination " + destination.getPath());
}
} catch (Exception e) {
result = false;
System.out.println(e.getMessage());
break;
}
}
} else {
result = false;
System.out.println("File " + src.getPath() + " doesn't exist.");
}
return result;
}
The file exist, but am keep getting errors when copying it to the destiny file like:
/storage/emulated/0/MyAppFolder/FolderCreatedByUser2/theFile.pdf: open failed: ENOENT (No such file or directory)
It fails in both streams, when trying to open the src file and/or destination file:
FileChannel srcChnl = new FileInputStream(src).getChannel();
FileChannel dstChnl = new FileOutputStream(destination).getChannel();
Permission to write are granted. The destination folders are created previously to the download of the file, the user can't select a destination if the directory isn't created.

destination = new File(to, srcName); creates a new File instance but does not create the underlying file. You can verify by checking destination.exists(). I believe all you need is:
destination = new File(to, srcName);
destination.createNewFile();
Also, your src path string manipulation and stuff in the first half of your code seems unnecessary and might be introducing an error that could be resolved with something more concise:
public static boolean copyFile(File src, File[] dst) {
boolean result = true;
if (src.exists()) {
String srcName = src.getName();
for (File file : dst) {
String to = file.getPath();
try {
File destination = new File(to, srcName);
if (destination.createNewFile()) {
FileChannel srcChnl = new FileInputStream(src).getChannel();
FileChannel dstChnl = new FileOutputStream(destination).getChannel();
dstChnl.transferFrom(srcChnl, 0, srcChnl.size());
srcChnl.close();
dstChnl.close();
} else {
result = false;
System.out.println("Unable to create destination " + destination.getPath());
}
} catch (Exception e) {
result = false;
System.out.println(e.getMessage());
break;
}
}
} else {
result = false;
System.out.println("File " + src.getPath() + " doesn't exist.");
}
return result;
}

Related

Renaming .jar file prevents program from extracting files

I am attempting to store some resources for my program within the runnable jar created through Intellij and then extract those files at runtime after receiving some user input. The folders are located on the root of the jar. I have got it to successfully extract the files as intended but the problems begin when the jar is renamed. As in applic1.jar to applic2.jar. Does anyone know why it is behaving in this manner?
This is the method that performs the extractions. Modified version of: How can I get a resource "Folder" from inside my jar File?
File jarFile = new File(getClass().getProtectionDomain().getCodeSource().getLocation().getPath());
boolean inDirectory = false;
if (jarFile.isFile()) { //run in JAR
try {
JarFile jar = new JarFile(jarFile);
Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) {
JarEntry currentJar = entries.nextElement();
String name = currentJar.getName();
Path currentFile = Paths.get(name).getFileName();
if (name.startsWith(oldPath.replaceAll(Pattern.quote("\\"), "/"))) {
if (currentJar.isDirectory()) {
Files.createDirectories(Paths.get(newPath));
inDirectory = true;
} else {
if (Files.notExists(Paths.get(newPath), LinkOption.NOFOLLOW_LINKS)) {
Files.createDirectories(Paths.get(newPath).getParent());
}
BufferedInputStream source = new BufferedInputStream(jar.getInputStream(currentJar));
File dest = new File(newPath + (inDirectory ? "\\" + currentFile : ""));
FileOutputStream fos = new FileOutputStream(dest);
int read;
while ((read = source.read()) != -1) {
fos.write(read);
fos.flush();
}
fos.close();
source.close();
}
}
}
jar.close();
} catch (IOException e) {
e.printStackTrace();
}
} else { //run in IDE
copyAndRename(oldPath, newPath);
}

Result of 'File.mkdirs()' is ignored

This is my Code inside myDir.mkdirs(); this code show me that warning of Result of File.mkdirs() is ignored.
I try to fix this Warning but I failed.
private void saveGIF() {
Toast.makeText(getApplicationContext(), "Gif Save", Toast.LENGTH_LONG).show();
String filepath123 = BuildConfig.VERSION_NAME;
try {
File myDir = new File(String.valueOf(Environment.getExternalStorageDirectory().toString()) + "/" + "NewyearGIF");enter code here
//My Statement Code This Line Show Me that Warning
myDir.mkdirs();
File file = new File(myDir, "NewyearGif_" + System.currentTimeMillis() + ".gif");
filepath123 = file.getPath();
InputStream is = getResources().openRawResource(this.ivDrawable);
BufferedInputStream bis = new BufferedInputStream(is);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] img = new byte[AccessibilityNodeInfoCompat.ACTION_NEXT_HTML_ELEMENT];
while (true) {
int current = bis.read();
if (current == -1) {
break;
}
baos.write(current);
}
FileOutputStream fos = new FileOutputStream(file);
fos.write(baos.toByteArray());
fos.flush();
fos.close();
is.close();
} catch (Exception e) {
e.printStackTrace();
}
Intent mediaScanIntent = new Intent("android.intent.action.MEDIA_SCANNER_SCAN_FILE");
mediaScanIntent.setData(Uri.fromFile(new File(filepath123)));
sendBroadcast(mediaScanIntent);
}
The method mkdirs has a boolean return value, which you didn't use.
boolean wasSuccessful = myDir.mkdirs();
The create operation returns a value, which indicates if the creation of the directory was successful. For example, the result value wasSuccessful can be used to display an error when it is false.
if (!wasSuccessful) {
System.out.println("was not successful.");
}
From the Java docs about the boolean return value:
true if and only if the directory was created, along with all
necessary parent directories; false otherwise
File CDir = new File(Environment.getExternalStorageDirectory(), IMPORT_DIRECTORY);
if (!CDir.exists()) {
boolean mkdir = CDir.mkdir();
if (!mkdir) {
Log.e(TAG, "Directory creation failed.");
}
}
mkdir return a Boolean value. we need to catch the return value from mkdir .Replace your code with this and check (warning of Result of File.mkdirs() is ignored.) will be gone
The idea behind the return-value of mkdir is, that every IO-Operation could fail and your program should react to this situation.
You can do:
if(myDirectory.exists() || myDirectory.mkdirs()) {
// Directory was created, can do anything you want
}
or you can just remove the warning using:
#SuppressWarnings("ResultOfMethodCallIgnored")
The mkdirs method checks if file exists but returns false if the directory was already created so you should check one more time using first method.
File myDirectory = new File(Environment.getExternalStorageDirectory(),"NewyearGIF");
if(!myDirectory.exists()) {
myDirectory.mkdirs();
}else{
// Directory already exist
}
This is a old question but still, the simplest way I've found is:
File imageThumbsDirectory = getBaseContext.getExternalFilesDir("ThumbTemp");
if(imageThumbsDirectory != null) {
if (!imageThumbsDirectory.exists()) {
if (imageThumbsDirectory.mkdir()) ; //directory is created;
}
}
Just put this code:
File myDirectory = new File(Environment.getExternalStorageDirectory(),"NewyearGIF");
if(!myDirectory.exists()) {
myDirectory.mkdirs();
}else{
// Directory already exist
}
If application running in above Lollipop, then you need to add runtime permission for storage.

How to create a directory, and save a picture to it in Android

This is a function I have written that tries to:
Create a folder with the users name
Save a .jpg inside of that
folder
The folder creation works fine, however when I try to save the pictures, they all save with the correct name, however they do not save in their intended folders. In other words, instead of having a folder containing a bunch of folders each containing one picture, I have one folder containing a bunch of empty folders, and a bunch of pictures all outside their folders (I can clarify if needed).
This is my code:
public void addToDir(List<Contact> list){
for(int i = 0; i < list.size(); i++){
String nameOfFolder = list.get(i).getName();
Bitmap currentBitmap = list.get(i).getBusiness_card();
String conName = Environment.getExternalStorageDirectory() + File.separator + "MyApp" + File.separator +
"Connected Accounts" + File.separator + nameOfFolder;
File conDir = new File(conName);
if (!conDir.mkdirs()) {
if (conDir.exists()) {
} else {
return;
}
}
try {
FileOutputStream fos = new FileOutputStream(conName + ".jpg", true);
currentBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
} catch (Exception e) {
Log.e("MyLog", e.toString());
}
}
}
I suspect the problem is with the FileOutputStream path, but I am not sure how to set it so that it is set to the folder I just created.
Much appreciated
This is how to define mFileTemp
String state = Environment.getExternalStorageState();
File mFileTemp;
if (Environment.MEDIA_MOUNTED.equals(state)) {
//this is like that
//directory : any folder name/you can add inner folders like that/your photo name122412414124.jpg
mFileTemp = new File(Environment.getExternalStorageDirectory()+File.separator+"any folder name"+File.separator+"you can add inner folders like that"
, "your photo name"+System.currentTimeMillis()+".jpg");
mFileTemp.getParentFile().mkdirs();
}
else {
mFileTemp = new File(getFilesDir()+"any folder name"+
File.separator+"myphotos")+File.separator+"profilephotos", "your photo name"+System.currentTimeMillis()+".jpg");
mFileTemp.getParentFile().mkdirs();
This is how i save any image
try {
InputStream inputStream = getContentResolver().openInputStream(data.getData());
FileOutputStream fileOutputStream = new FileOutputStream(mFileTemp);
copyStream(inputStream, fileOutputStream);
fileOutputStream.close();
inputStream.close();
} catch (Exception e) {
Log.e("error save", "Error while creating temp image", e);
}
And copyStream method
public static void copyStream(InputStream input, OutputStream output) throws IOException {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = input.read(buffer)) != -1) {
output.write(buffer, 0, bytesRead);
}
}

java copy file functions only works in debug mode

I have a piece of code to copy a specific file, I've used this functions for ages and it works properly.
The problem is that right now I'm writing a program with java awt/swing and my copyFile functions only works in debug mode...I can't understand why..
This is the error it throws:
can't copy directory: QQQ.wav
source file is unreadable: QQQ.wav
Error occoured QQQ.wav (The system cannot find the file specified)
But when I run the program in debug mode it works..!!
could anyone help me please???
Function copyFile:
public static void copyFile(File varFromFile, File varToFile) throws IOException {
// First make sure the source file exists, is a file, and is readable.
if (!varFromFile.exists())
System.err.println("no such source file: " + varFromFile);
if (!varFromFile.isFile())
System.err.println("can't copy directory: " + varFromFile);
if (!varFromFile.canRead())
System.err.println("source file is unreadable: " + varFromFile);
// If the destination is a directory, use the source file name
// as the destination file name
if (varToFile.isDirectory())
varToFile = new File(varToFile, varFromFile.getName());
// If the destination exists, make sure it is a writable file
// and ask before overwriting it. If the destination doesn't
// exist, make sure the directory exists and is writable.
if (varToFile.exists()) {
if (!varToFile.canWrite())
System.out.println("destination file is unwriteable: "
+ varToFile);
} else {
// If file doesn't exist, check if directory exists and is
// writable. If getParent() returns null, then the directory is
// the current directory. so look up the user. Directory system
// property to
// find out what that is.
// The destination directory
String varParent = varToFile.getParent();
// If none, use the current directory
if (varParent == null)
varParent = System.getProperty("user.dir");
// Convert it to a file.
File vardir = new File(varParent);
if (!vardir.exists())
System.out.print("destination directory doesn't exist: "
+ varParent);
if (vardir.isFile())
System.out
.print("destination is not a directory: " + varParent);
if (!vardir.canWrite())
System.out.print("destination directory is unwriteable: "
+ varParent);
}
// If we've gotten this far, then everything is okay.
// So we copy the file, a buffer of bytes at a time.
// Stream to read from source
FileInputStream varFromSource = null;
// Stream to write to destination
FileOutputStream VarToDestination = null;
try {
// Create input stream
varFromSource = new FileInputStream(varFromFile);
// Create output stream
VarToDestination = new FileOutputStream(varToFile);
// To hold file contents
byte[] buffer = new byte[4096];
// How many bytes in buffer
int bytes_read;
// Read until EOF
while ((bytes_read = varFromSource.read(buffer)) != -1)
VarToDestination.write(buffer, 0, bytes_read);
//System.out.println("File copied !!!");
} catch (Exception e) {
System.err.println("Error occoured " + e.getMessage());
} finally {
if (varFromSource != null) {
try {
varFromSource.close();
} catch (IOException e) {
System.err.println("Error is " + e.getMessage());
}
}
if (VarToDestination != null) {
try {
VarToDestination.close();
} catch (IOException e) {
System.err.println("Error is " + e.getMessage());
}
}
}

Get files from Jar which is on the repository without downloading the whole Jar from Java

I would like to access the jar file on the repository, search inside it for the certain files, retrieve those files and store them on my hard disc. I don't want to download the whole jar and then to search for it.
So let's assume I have the address of the Jar. Can someone provide me with the code for the rest of the problem?
public void searchInsideJar(final String jarUrl, final String artifactId,
final String artifactVersion) {
InputStream is = null;
OutputStream outStream = null;
JarInputStream jis = null;
int i = 1;
try {
String strDirectory = "C:/Users/ilijab/" + artifactId +artifactVersion;
// Create one directory
boolean success = (new File(strDirectory)).mkdir();
if (success) {
System.out.println("Directory: " + strDirectory + " created");
}
is = new URL(jarUrl).openStream();
jis = new JarInputStream(is);
while (true) {
JarEntry ent = jis.getNextJarEntry();
if (ent == null) {
break;
}
if (ent.isDirectory()) {
continue;
}
if (ent.getName().contains("someFile")) {
outStream = new BufferedOutputStream(new FileOutputStream(
strDirectory + "\\" + "someFile" + i));
while(ent.)
System.out.println("**************************************************************");
System.out.println(i);
i++;
}
}
} catch (Exception ex) {
}
}
So, in upper code, how can I save the file I found(the last if) into directory.
Assuming that by "repository", you mean a Maven repository, then i'm afraid this can't be done. Maven repositories let you download artifacts, like jar files, but won't look inside them for you.

Categories

Resources