Im trying to copy a file in java and move it to a new folder. This is the code i HAve been using but I always get this error "(Access is denied) in the specified directory". Is there a way i can fix this or a better way to copy the files? thanks
try{
File f1 = new File(fpath);
File f2 = new File("C:/users/peter/documents/foldertest2/hats");
InputStream in = new FileInputStream(f1);
//For Append the file.
//OutputStream out = new FileOutputStream(f2,true);
//For Overwrite the file.
OutputStream out = new FileOutputStream(f2);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0){
out.write(buf, 0, len);
}
in.close();
out.close();
System.out.println("File copied.");
}
catch(FileNotFoundException ex){
System.out.println(ex.getMessage() + " in the specified directory.");
System.exit(0);
}
catch(IOException e){
System.out.println(e.getMessage());
}
UPDATE:
I checked the folder permissions and they are all open for all users and mine
Apache Commons IO is also another way to go, specifically FileUtils.copyFile(); it handles all the heavy lifting for you.
Use Java 7:
import static java.nio.file.StandardCopyOption.*;
Files.copy(source, target, REPLACE_EXISTING);
http://docs.oracle.com/javase/tutorial/essential/io/copy.html
Is there a way i can fix this or a better way to copy the files?
If you have the option, I would recommend you to go with Java version 7, and use the Path.copyTo method.
Copy the file located by this path to a target location. [...]
Otherwise I would recommend at least using the NIO packages and FileChannels.
Edit ups messed up, second try:
You have to give the FileOutputStream a valid file name, just append the name of your file to the target path C:/users/peter/documents/foldertest2/hats/hat3 with only the folder name it will try to access the folder as if it was a file and fail.
If you get this exception the access is really denied, i.e. you just do not have rights to write to the specified directory or file.
So, first check it. Try for example to create the file in specified directory manually. Do you probably try to create file in somebody else' home directory? Or your java program is running as other user? What about foldertest2? Does it exist and writable? Try to copy your file there.
And the final tip. When you manage to copy the file, I'd recommend you to use IOUtils.copy() (from jacarta commons). I use it a lot. It does almost exactly what you implemented but have to write of code one line only.
Hmm it looks like you are trying to run this on windows, should you not be using \ in your path instead of / ?
As AlexR said check your permissions on the directory you are trying to write to.
Related
Is there a way in Java to construct a File instance on a resource retrieved from a jar through the classloader?
My application uses some files from the jar (default) or from a filesystem directory specified at runtime (user input). I'm looking for a consistent way of
a) loading these files as a stream
b) listing the files in the user-defined directory or the directory in the jar respectively
Edit: Apparently, the ideal approach would be to stay away from java.io.File altogether. Is there a way to load a directory from the classpath and list its contents (files/entities contained in it)?
I had the same problem and was able to use the following:
// Load the directory as a resource
URL dir_url = ClassLoader.getSystemResource(dir_path);
// Turn the resource into a File object
File dir = new File(dir_url.toURI());
// List the directory
String files = dir.list()
ClassLoader.getResourceAsStream and Class.getResourceAsStream are definitely the way to go for loading the resource data. However, I don't believe there's any way of "listing" the contents of an element of the classpath.
In some cases this may be simply impossible - for instance, a ClassLoader could generate data on the fly, based on what resource name it's asked for. If you look at the ClassLoader API (which is basically what the classpath mechanism works through) you'll see there isn't anything to do what you want.
If you know you've actually got a jar file, you could load that with ZipInputStream to find out what's available. It will mean you'll have different code for directories and jar files though.
One alternative, if the files are created separately first, is to include a sort of manifest file containing the list of available resources. Bundle that in the jar file or include it in the file system as a file, and load it before offering the user a choice of resources.
Here is a bit of code from one of my applications...
Let me know if it suits your needs.
You can use this if you know the file you want to use.
URL defaultImage = ClassA.class.getResource("/packageA/subPackage/image-name.png");
File imageFile = new File(defaultImage.toURI());
A reliable way to construct a File instance on a resource retrieved from a jar is it to copy the resource as a stream into a temporary File (the temp file will be deleted when the JVM exits):
public static File getResourceAsFile(String resourcePath) {
try {
InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(resourcePath);
if (in == null) {
return null;
}
File tempFile = File.createTempFile(String.valueOf(in.hashCode()), ".tmp");
tempFile.deleteOnExit();
try (FileOutputStream out = new FileOutputStream(tempFile)) {
//copy stream
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
}
return tempFile;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
Try this:
ClassLoader.getResourceAsStream ("some/pkg/resource.properties");
There are more methods available, e.g. see here:
http://www.javaworld.com/javaworld/javaqa/2003-08/01-qa-0808-property.html
This is one option: http://www.uofr.net/~greg/java/get-resource-listing.html
I am making a 1 file program in java, and I have a .chm file that I want to be called when the user asks how to use the program. I don't want to have the file outside the .jar file.
Maybe what I'm asking is impossible, the only thing I know about compiling is that if I hit "clean and build" button it generates a .jar file out of my .java files. Is there a way to do this?
PS: I use NetBeans to create java programs.
You can include any file inside a jar (it is a zip file). Then you have to use getResource() to get an access to the embedded file in your jar. That would return an URL that you can use to get an InputStream by calling openStream() and read from it, possibly extracting it to the hard drive for display, etc.
The use is to put such files in a "resource" or "res" folder, inside the "src" directory. Here is how it looks in my Eclipse:
Then I access my images by:
URL uImg = getClass().getResource("/res/16/Actions-edit-delete-icon-16.png");
InputStream is = uImg.openStream();
// Read the content from 'is' e.g. to extract it somewhere
is.close();
EDIT: As an example, to extract your file "TJ.chm" from "res" directory of your jar into a file "/tmp/TJ.chm" you would do like:
// Add all necessary try/catch
InputStream is = ucmh.openStream();
OutputStream os = new BufferedOutputStream(new FileOutputStream("/tmp/TJ.chm"));
int len = 0;
byte[] buffer = new byte[8192]; // Or whichever size you prefer
while ((len = is.read(buffer)) > -1)
os.write(buffer, 0, len);
os.close();
is.close();
I'm trying to access a shared file from my app, e.g //172.24.9.13/c/2012xp.mdb
By doing:
new File("//172.24.9.13/c/2012xp.mdb");
it doesn't work.
I found the jCIFS library, and creating
new SmbFile("//172.24.9.13/c/2012xp.mdb");
it works, but the problem is that I need a java.io.File.
I have also seen that there is no way to mount smb's on android devices without rooting them.
Is there a way to get a java.io.File instance of my shared file?
I don't think you'll be able to read it as java.io.File because it's not one.
If you absolutely need a java.io.File you'll probably have to call smbFile.getInputStream() and copy to a local file, than you use that local file.
Considering it's a .mdb file you're probably wanting to read data from the DataBase, and it might be a huge file and you don't want to copy it over. On that situation, your only option is to setup a server, with an api that replies in JSON and your app will send GET requests to it.
try this code. i'm not sure about .mdb file format. but this works for PDF files.
first create a SmbFileInputStream using your smb file.
in = new SmbFileInputStream(sFile);
Then create a output file in the device storage (SD card)
outputfile = new File(dir, "todevice.pdf");
Then create a FileOutputStream (java IO)
out = new FileOutputStream(outputfile);
Then read input(SMB) and write it in to the output(IO)
while ((read = in.read(buffer)) > 0 )
{
try {
out.write(buffer, 0, read);
} catch (IOException e) {
}
}
Now u have a file on your sd card
Is there a way in Java to construct a File instance on a resource retrieved from a jar through the classloader?
My application uses some files from the jar (default) or from a filesystem directory specified at runtime (user input). I'm looking for a consistent way of
a) loading these files as a stream
b) listing the files in the user-defined directory or the directory in the jar respectively
Edit: Apparently, the ideal approach would be to stay away from java.io.File altogether. Is there a way to load a directory from the classpath and list its contents (files/entities contained in it)?
I had the same problem and was able to use the following:
// Load the directory as a resource
URL dir_url = ClassLoader.getSystemResource(dir_path);
// Turn the resource into a File object
File dir = new File(dir_url.toURI());
// List the directory
String files = dir.list()
ClassLoader.getResourceAsStream and Class.getResourceAsStream are definitely the way to go for loading the resource data. However, I don't believe there's any way of "listing" the contents of an element of the classpath.
In some cases this may be simply impossible - for instance, a ClassLoader could generate data on the fly, based on what resource name it's asked for. If you look at the ClassLoader API (which is basically what the classpath mechanism works through) you'll see there isn't anything to do what you want.
If you know you've actually got a jar file, you could load that with ZipInputStream to find out what's available. It will mean you'll have different code for directories and jar files though.
One alternative, if the files are created separately first, is to include a sort of manifest file containing the list of available resources. Bundle that in the jar file or include it in the file system as a file, and load it before offering the user a choice of resources.
Here is a bit of code from one of my applications...
Let me know if it suits your needs.
You can use this if you know the file you want to use.
URL defaultImage = ClassA.class.getResource("/packageA/subPackage/image-name.png");
File imageFile = new File(defaultImage.toURI());
A reliable way to construct a File instance on a resource retrieved from a jar is it to copy the resource as a stream into a temporary File (the temp file will be deleted when the JVM exits):
public static File getResourceAsFile(String resourcePath) {
try {
InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(resourcePath);
if (in == null) {
return null;
}
File tempFile = File.createTempFile(String.valueOf(in.hashCode()), ".tmp");
tempFile.deleteOnExit();
try (FileOutputStream out = new FileOutputStream(tempFile)) {
//copy stream
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
}
return tempFile;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
Try this:
ClassLoader.getResourceAsStream ("some/pkg/resource.properties");
There are more methods available, e.g. see here:
http://www.javaworld.com/javaworld/javaqa/2003-08/01-qa-0808-property.html
This is one option: http://www.uofr.net/~greg/java/get-resource-listing.html
I am trying to copy a file using the following code:
File targetFile = new File(targetPath + File.separator + filename);
...
targetFile.createNewFile();
fileInputStream = new FileInputStream(fileToCopy);
fileOutputStream = new FileOutputStream(targetFile);
byte[] buffer = new byte[64*1024];
int i = 0;
while((i = fileInputStream.read(buffer)) != -1) {
fileOutputStream.write(buffer, 0, i);
}
For some users the targetFile.createNewFile results in this exception:
java.io.IOException: The filename, directory name, or volume label syntax is incorrect
at java.io.WinNTFileSystem.createFileExclusively(Native Method)
at java.io.File.createNewFile(File.java:850)
Filename and directory name seem to be correct. The directory targetPath is even checked for existence before the copy code is executed and the filename looks like this: AB_timestamp.xml
The user has write permissions to the targetPath and can copy the file without problems using the OS.
As I don't have access to a machine this happens on yet and can't reproduce the problem on my own machine I turn to you for hints on the reason for this exception.
This can occur when filename has timestamp with colons, eg. myfile_HH:mm:ss.csv Removing colons fixed the issue.
Try this, as it takes more care of adjusting directory separator characters in the path between targetPath and filename:
File targetFile = new File(targetPath, filename);
I just encountered the same problem. I think it has to something do with write access permission. I got the error while trying to write to c:\ but on changing to D:\ everything worked fine.
Apparently Java did not have permission to write to my System Drive (Running Windows 7 installed on C:)
Here is the test program I use
import java.io.File;
public class TestWrite {
public static void main(String[] args) {
if (args.length!=1) {
throw new IllegalArgumentException("Expected 1 argument: dir for tmp file");
}
try {
File.createTempFile("bla",".tmp",new File(args[0]));
} catch (Exception e) {
System.out.println("exception:"+e);
e.printStackTrace();
}
}
}
Try to create the file in a different directory - e.g. "C:\" after you made sure you have write access to that directory. If that works, the path name of the file is wrong.
Take a look at the comment in the Exception and try to vary all the elements in the path name of the file. Experiment. Draw conclusions.
Remove any special characters in the file/folder name in the complete path.
Do you check that the targetPath is a directory, or just that something exists with that name? (I know you say the user can copy it from the operating system, but maybe they're typing something else).
Does targetPath end with a File.separator already?
(It would help if you could log and tell us what the value of targetPath and filename are on a failing case)
Maybe the problem is that it is copying the file over the network, to a shared drive? I think java can have problems when writing files using NFS when the path is something like \mypc\myshared folder.
What is the path where this problem happens?
Try adding some logging to see exactly what is the name and path the file is trying to create, to ensure that the parent is well a directory.
In addition, you can also take a look at Channels instead of using a loop. ;-)
You say "for some users" - so it works for others? What is the difference here, are the users running different instances on different machines, or is this a server that services concurrent users?
If the latter, I'd say it is a concurrency bug somehow - two threads check try to create the file with WinNTFileSystem.createFileExclusively(Native Method) simultaniously.
Neither createNewFile or createFileExclusively are synchronized when I look at the OpenJDK source, so you may have to synchronize this block yourself.
Maybe the file already exists. It could be the case if your timestamp resolution is not good enough. As it is an IOException that you are getting, it might not be a permission issue (in which case you would get a SecurityException).
I would first check for file existence before trying to create the file and try to log what's happening.
Look at public boolean createNewFile() for more information on the method you are using.
As I was not able to reproduce the error on my own machine or get hands on the machine of the user where the code failed I waited until now to declare an accepted answer.
I changed the code to the following:
File parentFolder = new File(targetPath);
... do some checks on parentFolder here ...
File targetFile = new File(parentFolder, filename);
targetFile.createNewFile();
fileInputStream = new FileInputStream(fileToCopy);
fileOutputStream = new FileOutputStream(targetFile);
byte[] buffer = new byte[64*1024];
int i = 0;
while((i = fileInputStream.read(buffer)) != -1) {
fileOutputStream.write(buffer, 0, i);
}
After that it worked for the user reporting the problem.
So it seems Alexanders answer did the trick - although I actually use a slightly different constructor than he gave, but along the same lines.
I yet have to talk that user into helping me verifying that the code change fixed the error (instead of him doing something differently) by running the old version again and checking if it still fails.
btw. logging was in place and the logged path seemed ok - sorry for not mentioning that. I took that for granted and found it unnecessarily complicated the code in the question.
Thanks for the helpful answers.
A very similar error:-
" ... java.io.IOException: The filename, directory name, or volume label syntax is incorrect"
was generated in Eclipse for me when the TOMCAT home setting had a training backslash.
The minor edit suggested at:-
http://www.coderanch.com/t/556633/Tomcat/java-io-IOException-filename-directory
fixed it for me.
FileUtils.copyFile(src,new File("C:\\Users\\daiva\\eclipse-workspace\\PracticeProgram\\Screenshot\\adi.png"));
Try to copy file like this.