I have an assignment for my CS class where it says to read a file with several test scores and asks me to sum and average them. While summing and averaging is easy, I am having problems with the file reading. The instructor said to use this syntax
Scanner scores = new Scanner(new File("scores.dat"));
However, this throws a FileNotFoundException, but I have checked over and over again to see if the file exists in the current folder, and after that, I figured that it had to do something with the permissions. I changed the permissions for read and write for everyone, but it still did not work and it still keeps throwing the error. Does anyone have any idea why this may be occurring?
EDIT: It was actually pointing to a directory up, however, I have fixed that problem. Now file.exists() returns true, but when I try to put it in the Scanner, it throws the FileNotFoundException
Here is all my code
import java.util.Scanner;
import java.io.*;
public class readInt{
public static void main(String args[]){
File file = new File("lines.txt");
System.out.println(file.exists());
Scanner scan = new Scanner(file);
}
}
There are a number situation where a FileNotFoundException may be thrown at runtime.
The named file does not exist. This could be for a number of reasons including:
The pathname is simply wrong
The pathname looks correct but is actually wrong because it contains non-printing characters (or homoglyphs) that you did not notice
The pathname is relative, and it doesn't resolve correctly relative to the actual current directory of the running application. This typically happens because the application's current directory is not what you are expecting or assuming.
The path to the file is is broken; e.g. a directory name of the path is incorrect, a symbolic link on the path is broken, or there is a permission problem with one of the path components.
The named file is actually a directory.
The named file cannot be opened for reading for some reason.
The good news that, the problem will inevitably be one of the above. It is just a matter of working out which. Here are some things that you can try:
Calling file.exists() will tell you if any file system object exists with the given name / pathname.
Calling file.isDirectory() will test if it is a directory.
Calling file.canRead() will test if it is a readable file.
This line will tell you what the current directory is:
System.out.println(new File(".").getAbsolutePath());
This line will print out the pathname in a way that makes it easier to spot things like unexpected leading or trailing whitespace:
System.out.println("The path is '" + path + "'");
Look for unexpected spaces, line breaks, etc in the output.
It turns out that your example code has a compilation error.
I ran your code without taking care of the complaint from Netbeans, only to get the following exception message:
Exception in thread "main" java.lang.RuntimeException: Uncompilable
source code - unreported exception java.io.FileNotFoundException; must
be caught or declared to be thrown
If you change your code to the following, it will fix that problem.
public static void main(String[] args) throws FileNotFoundException {
File file = new File("scores.dat");
System.out.println(file.exists());
Scanner scan = new Scanner(file);
}
Explanation: the Scanner(File) constructor is declared as throwing the FileNotFoundException exception. (It happens the scanner it cannot open the file.) Now FileNotFoundException is a checked exception. That means that a method in which the exception may be thrown must either catch the exception or declare it in the throws clause. The above fix takes the latter approach.
The code itself is working correctly. The problem is, that the program working path is pointing to other place than you think.
Use this line and see where the path is:
System.out.println(new File(".").getAbsoluteFile());
Obviously there are a number of possible causes and the previous answers document them well, but here's how I solved this for in one particular case:
A student of mine had this problem and I nearly tore my hair out trying to figure it out. It turned out that the file didn't exist, even though it looked like it did. The problem was that Windows 7 was configured to "Hide file extensions for known file types." This means that if file appears to have the name "data.txt" its actual filename is "data.txt.txt".
Hope this helps others save themselves some hair.
I recently found interesting case that produces FileNotFoundExeption when file is obviously exists on the disk.
In my program I read file path from another text file and create File object:
//String path was read from file
System.out.println(path); //file with exactly same visible path exists on disk
File file = new File(path);
System.out.println(file.exists()); //false
System.out.println(file.canRead()); //false
FileInputStream fis = new FileInputStream(file); // FileNotFoundExeption
The cause of the problem was that the path contained invisible \r\n characters at the end.
The fix in my case was:
File file = new File(path.trim());
To generalize a bit, the invisible / non-printing characters could have include space or tab characters, and possibly others, and they could have appeared at the beginning of the path, at the end, or embedded in the path. Trim will work in some cases but not all. There are a couple of things that you can help to spot this kind of problem:
Output the pathname with quote characters around it; e.g.
System.out.println("Check me! '" + path + "'");
and carefully check the output for spaces and line breaks where they shouldn't be.
Use a Java debugger to carefully examine the pathname string, character by character, looking for characters that shouldn't be there. (Also check for homoglyph characters!)
An easy fix, which worked for me, is moving my files out of src and into the main folder of the project. It's not the best solution, but depending on the magnitude of the project and your time, it might be just perfect.
Reading and writing from and to a file can be blocked by your OS depending on the file's permission attributes.
If you are trying to read from the file, then I recommend using File's setReadable method to set it to true, or, this code for instance:
String arbitrary_path = "C:/Users/Username/Blah.txt";
byte[] data_of_file;
File f = new File(arbitrary_path);
f.setReadable(true);
data_of_file = Files.readAllBytes(f);
f.setReadable(false); // do this if you want to prevent un-knowledgeable
//programmers from accessing your file.
If you are trying to write to the file, then I recommend using File's setWritable method to set it to true, or, this code for instance:
String arbitrary_path = "C:/Users/Username/Blah.txt";
byte[] data_of_file = { (byte) 0x00, (byte) 0xFF, (byte) 0xEE };
File f = new File(arbitrary_path);
f.setWritable(true);
Files.write(f, byte_array);
f.setWritable(false); // do this if you want to prevent un-knowledgeable
//programmers from changing your file (for security.)
Apart from all the other answers mentioned here, you can do one thing which worked for me.
If you are reading the path through Scanner or through command line args, instead of copy pasting the path directly from Windows Explorer just manually type in the path.
It worked for me, hope it helps someone :)
I had this same error and solved it simply by adding the src directory that is found in Java project structure.
String path = System.getProperty("user.dir") + "\\src\\package_name\\file_name";
File file = new File(path);
Scanner scanner = new Scanner(file);
Notice that System.getProperty("user.dir") and new File(".").getAbsolutePath() return your project root directory path, so you have to add the path to your subdirectories and packages
You'd obviously figure it out after a while but just posting this so that it might help someone. This could also happen when your file path contains any whitespace appended or prepended to it.
Use single forward slash and always type the path manually. For example:
FileInputStream fi= new FileInputStream("D:/excelfiles/myxcel.xlsx");
What worked for me was catching the exception. Without it the compiler complains even if the file exists.
InputStream file = new FileInputStream("filename");
changed to
try{
InputStream file = new FileInputStream("filename");
System.out.println(file.available());
}
catch (Exception e){
System.out.println(e);
}
This works for me. It also can read files such txt, csv and .in
public class NewReader {
public void read() throws FileNotFoundException, URISyntaxException {
File file = new File(Objects.requireNonNull(NewReader.class.getResource("/test.txt")).toURI());
Scanner sc = new Scanner(file);
while (sc.hasNext()) {
String text = sc.next();
System.out.println(text);
}
}
}
the file is located in resource folder generated by maven. If you have other folders nested in, just add it to the file name like "examples/test.txt".
Related
I have an assignment for my CS class where it says to read a file with several test scores and asks me to sum and average them. While summing and averaging is easy, I am having problems with the file reading. The instructor said to use this syntax
Scanner scores = new Scanner(new File("scores.dat"));
However, this throws a FileNotFoundException, but I have checked over and over again to see if the file exists in the current folder, and after that, I figured that it had to do something with the permissions. I changed the permissions for read and write for everyone, but it still did not work and it still keeps throwing the error. Does anyone have any idea why this may be occurring?
EDIT: It was actually pointing to a directory up, however, I have fixed that problem. Now file.exists() returns true, but when I try to put it in the Scanner, it throws the FileNotFoundException
Here is all my code
import java.util.Scanner;
import java.io.*;
public class readInt{
public static void main(String args[]){
File file = new File("lines.txt");
System.out.println(file.exists());
Scanner scan = new Scanner(file);
}
}
There are a number situation where a FileNotFoundException may be thrown at runtime.
The named file does not exist. This could be for a number of reasons including:
The pathname is simply wrong
The pathname looks correct but is actually wrong because it contains non-printing characters (or homoglyphs) that you did not notice
The pathname is relative, and it doesn't resolve correctly relative to the actual current directory of the running application. This typically happens because the application's current directory is not what you are expecting or assuming.
The path to the file is is broken; e.g. a directory name of the path is incorrect, a symbolic link on the path is broken, or there is a permission problem with one of the path components.
The named file is actually a directory.
The named file cannot be opened for reading for some reason.
The good news that, the problem will inevitably be one of the above. It is just a matter of working out which. Here are some things that you can try:
Calling file.exists() will tell you if any file system object exists with the given name / pathname.
Calling file.isDirectory() will test if it is a directory.
Calling file.canRead() will test if it is a readable file.
This line will tell you what the current directory is:
System.out.println(new File(".").getAbsolutePath());
This line will print out the pathname in a way that makes it easier to spot things like unexpected leading or trailing whitespace:
System.out.println("The path is '" + path + "'");
Look for unexpected spaces, line breaks, etc in the output.
It turns out that your example code has a compilation error.
I ran your code without taking care of the complaint from Netbeans, only to get the following exception message:
Exception in thread "main" java.lang.RuntimeException: Uncompilable
source code - unreported exception java.io.FileNotFoundException; must
be caught or declared to be thrown
If you change your code to the following, it will fix that problem.
public static void main(String[] args) throws FileNotFoundException {
File file = new File("scores.dat");
System.out.println(file.exists());
Scanner scan = new Scanner(file);
}
Explanation: the Scanner(File) constructor is declared as throwing the FileNotFoundException exception. (It happens the scanner it cannot open the file.) Now FileNotFoundException is a checked exception. That means that a method in which the exception may be thrown must either catch the exception or declare it in the throws clause. The above fix takes the latter approach.
The code itself is working correctly. The problem is, that the program working path is pointing to other place than you think.
Use this line and see where the path is:
System.out.println(new File(".").getAbsoluteFile());
Obviously there are a number of possible causes and the previous answers document them well, but here's how I solved this for in one particular case:
A student of mine had this problem and I nearly tore my hair out trying to figure it out. It turned out that the file didn't exist, even though it looked like it did. The problem was that Windows 7 was configured to "Hide file extensions for known file types." This means that if file appears to have the name "data.txt" its actual filename is "data.txt.txt".
Hope this helps others save themselves some hair.
I recently found interesting case that produces FileNotFoundExeption when file is obviously exists on the disk.
In my program I read file path from another text file and create File object:
//String path was read from file
System.out.println(path); //file with exactly same visible path exists on disk
File file = new File(path);
System.out.println(file.exists()); //false
System.out.println(file.canRead()); //false
FileInputStream fis = new FileInputStream(file); // FileNotFoundExeption
The cause of the problem was that the path contained invisible \r\n characters at the end.
The fix in my case was:
File file = new File(path.trim());
To generalize a bit, the invisible / non-printing characters could have include space or tab characters, and possibly others, and they could have appeared at the beginning of the path, at the end, or embedded in the path. Trim will work in some cases but not all. There are a couple of things that you can help to spot this kind of problem:
Output the pathname with quote characters around it; e.g.
System.out.println("Check me! '" + path + "'");
and carefully check the output for spaces and line breaks where they shouldn't be.
Use a Java debugger to carefully examine the pathname string, character by character, looking for characters that shouldn't be there. (Also check for homoglyph characters!)
An easy fix, which worked for me, is moving my files out of src and into the main folder of the project. It's not the best solution, but depending on the magnitude of the project and your time, it might be just perfect.
Reading and writing from and to a file can be blocked by your OS depending on the file's permission attributes.
If you are trying to read from the file, then I recommend using File's setReadable method to set it to true, or, this code for instance:
String arbitrary_path = "C:/Users/Username/Blah.txt";
byte[] data_of_file;
File f = new File(arbitrary_path);
f.setReadable(true);
data_of_file = Files.readAllBytes(f);
f.setReadable(false); // do this if you want to prevent un-knowledgeable
//programmers from accessing your file.
If you are trying to write to the file, then I recommend using File's setWritable method to set it to true, or, this code for instance:
String arbitrary_path = "C:/Users/Username/Blah.txt";
byte[] data_of_file = { (byte) 0x00, (byte) 0xFF, (byte) 0xEE };
File f = new File(arbitrary_path);
f.setWritable(true);
Files.write(f, byte_array);
f.setWritable(false); // do this if you want to prevent un-knowledgeable
//programmers from changing your file (for security.)
Apart from all the other answers mentioned here, you can do one thing which worked for me.
If you are reading the path through Scanner or through command line args, instead of copy pasting the path directly from Windows Explorer just manually type in the path.
It worked for me, hope it helps someone :)
I had this same error and solved it simply by adding the src directory that is found in Java project structure.
String path = System.getProperty("user.dir") + "\\src\\package_name\\file_name";
File file = new File(path);
Scanner scanner = new Scanner(file);
Notice that System.getProperty("user.dir") and new File(".").getAbsolutePath() return your project root directory path, so you have to add the path to your subdirectories and packages
You'd obviously figure it out after a while but just posting this so that it might help someone. This could also happen when your file path contains any whitespace appended or prepended to it.
Use single forward slash and always type the path manually. For example:
FileInputStream fi= new FileInputStream("D:/excelfiles/myxcel.xlsx");
What worked for me was catching the exception. Without it the compiler complains even if the file exists.
InputStream file = new FileInputStream("filename");
changed to
try{
InputStream file = new FileInputStream("filename");
System.out.println(file.available());
}
catch (Exception e){
System.out.println(e);
}
This works for me. It also can read files such txt, csv and .in
public class NewReader {
public void read() throws FileNotFoundException, URISyntaxException {
File file = new File(Objects.requireNonNull(NewReader.class.getResource("/test.txt")).toURI());
Scanner sc = new Scanner(file);
while (sc.hasNext()) {
String text = sc.next();
System.out.println(text);
}
}
}
the file is located in resource folder generated by maven. If you have other folders nested in, just add it to the file name like "examples/test.txt".
I am trying to read a file in Java. I wrote a program and saved the file in the exact same folder as my program. Yet, I keep getting a FileNotFoundException. Here is the code:
public static void main(String[] args) throws IOException {
Hashtable<String, Integer> ht = new Hashtable<String, Integer>();
File f = new File("file.txt");
ArrayList<String> al = readFile(f, ht);
}
public static ArrayList<String> readFile(File f, Hashtable<String, Integer> ht) throws IOException{
ArrayList<String> al = new ArrayList<String>();
BufferedReader br = new BufferedReader(new FileReader(f));
String line = "";
int ctr = 0;
}
...
return al;
}
Here is the stack trace:
Exception in thread "main" java.io.FileNotFoundException: file.txt (The system cannot find the file specified)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(Unknown Source)
at java.io.FileReader.<init>(Unknown Source)
at csfhomework3.ScramAssembler.readFile(ScramAssembler.java:26)
at csfhomework3.ScramAssembler.main(ScramAssembler.java:17)
I don't understand how the file can't be found if it's in the exact same folder as the program. I'm running the program in eclipse and I checked my run configurations for any stray arguments and there are none. Does anyone see what's wrong?
Because the File isn't where you think it is. Print the path that your program is attempting to read.
File f = new File("file.txt");
try {
System.out.println(f.getCanonicalPath());
} catch (IOException e) {
e.printStackTrace();
}
Per the File.getCanonicalPath() javadoc, A canonical pathname is both absolute and unique. The precise definition of canonical form is system-dependent.
Check the Eclipse run configuration. Look on the second tab "Arguments", at the bottom pane where it says "Working Directory". That's the place where the program gets launched and where it will expect to find the file. Usually in Eclipse it launches your program with the current working directory set to be the base project directory. If you have the java class file in a source folder and are using proper package (e.g., "com.mycompany.package"), then the data file will be in a directory like "src/com/mycompany/package" which is quite a different directory from the project directory.
HTH
File needs to be in the class path and not in the source path. Copy the file in output/class files folder and it should be available.
You should probably check out this question: Java can't find file when running through Eclipse
Basically you need to be sure where the execution is taking place (current directory) and how your SO will resolve the relative paths. Try changing the working directory in Eclipse' Run Configurations>Arguments or provide the absolute filename
I'm extremely late to responding to this question, but I see that this is still an extremely hot topic to this day. It may not seem obvious, but what you want to use here is actually the newer file-handling i/o library, java.nio. The below explained example shows how to read a String from a file path, but I encourage you to take a look at the docs if you have a different use.
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Files;
public static void main(String[] args) throws IOException {
Path path = Path.of("app/src/main/java/pkgname/file.txt");
String content = Files.readString(path);
System.out.println(content); // Prints file content
}
Okay, code done, now time for the explanation. I'll start off with the import statements. java.io.IOException is necessary for some exception-handling. (Sidenote: Do not omit the throws IOException and/or the IOException import. Otherwise Files.readString() may throw an error in your editor, which I'll get to shortly). The Path class import is necessary to actually get the file, and the Files class import is necessary for file operations.
Now, the main function itself. The first line receives a Path object representing a file for you to actually read/write. Here the question of path name arises, which is the basis of the question. I have seen other solutions that tell you to take the absolute path of your file, but don't do that! It's extremely bad practice, especially with open-source or public code. Path.of actually allows you to use the path relative to your root folder (unless it isn't in a directory, simply inputting the file name does not work, I'm afraid). The example path name I gave is an example of a Gradle project. Next line, we get the content of the file as a String using a method from Files. Again, if you have a different use for a file, you can check the docs (a different method from the Files class will probably work for you). On the final line, we print the result. Hooray! Our output is just what we needed.
There you have it, using Path instead of File is the solution to this annoying bug. Hopefully this helps!
I'm using Eclipse (SDK v4.2.2) to develop a Java project (Java SE, v1.6) that currently reads information from external .txt files as part of methods used many times in a single pass. I would like to include these files in my project, making them "native" to make the project independent of external files. I don't know where to add the files into the project or how to add them so they can easily be used by the appropriate method.
Searching on Google has not turned up any solid guidance, nor have I found any similar questions on this site. If someone knows how to do add files and where they should go, I'd greatly appreciate any advice or even a point in the right direction. Also, if any additional information about the code or the .txt files is required, I'll be happy to provide as much detail as possible.
UPDATE 5/20/2013: I've managed to get the text files into the classpath; they're located in a package under a folder called 'resc' (per dharam's advice), which is on the same classpath level as the 'src' folder in which my code is packaged. Now I just need to figure out how to get my code to read these files properly. Specifically, I want to read a selected file into a two-dimensional array, reading line-by-line and splitting each line by a delimiter. Prior to packaging the files directly within the workspace, I used a BufferedReader to do this:
public static List<String[]> fileRead(String d) {
// Initialize File 'f' with path completed by passed-in String 'd'.
File f = new File("<incomplete directory path goes here>" + d);
// Initialize some variables to be used shortly.
String s = null;
List<String> a = new ArrayList<String>();
List<String[]> l = new ArrayList<String[]>();
try {
// Use new BufferedReader 'in' to read in 'f'.
BufferedReader in = new BufferedReader(new FileReader(f));
// Read the first line into String 's'.
s = in.readLine();
// So long as 's' is NOT null...
while(s != null) {
// Split the current line, using semi-colons as delimiters, and store in 'a'.
// Convert 'a' to array 'aSplit', then add 'aSplit' to 'l'.
a = Arrays.asList(s.split("\\s*;\\s*"));
String[] aSplit = a.toArray(new String[2]);
l.add(aSplit);
// Read next line of 'f'.
s = in.readLine();
}
// Once finished, close 'in'.
in.close();
} catch (IOException e) {
// If problems occur during 'try' code, catch exception and include StackTrace.
e.printStackTrace();
}
// Return value of 'l'.
return l;
}
If I decide to use the methods described in the link provided by Pangea (using getResourceAsStream to read in the file as an InputStream), I'm not sure how I would be able to achieve the same results. Would someone be able to help me find a solution on this same question, or should I ask about that issue into a different question to prevent headaches?
You can put them anywhere you wish, but depends on what you want to achieve through putting the file.
A general practice is to create a folder with name resc/resource and put files in it. Include the folder in classpath.
You can store the files within a java package and read them as classpath resources. For e.g. you can add the text files to a java package say com.foo and use this thread to know how to read them: How to really read text file from classpath in Java
This way they are independent of the environment and are co-packaged with code itself.
Add the files in the projects classpath.(you can find the class path of the project by right click the project in eclipse->Build Path->configure build path)
I guess you want an internal .txt file.
Package Explorer => Right Click at your project => New => File . Then text a file name and Finish it.
The path in your code should look like this:
Scanner diskScanner = new Scanner(new File("YourFile"));
Im trying to write a program to read a text file through args but when i run it, it always says the file can't be found even though i placed it inside the same folder as the main.java that im running.
Does anyone know the solution to my problem or a better way of reading a text file?
Do not use relative paths in java.io.File.
It will become relative to the current working directory which is dependent on the way how you run the application which in turn is not controllable from inside your application. It will only lead to portability trouble. If you run it from inside Eclipse, the path will be relative to /path/to/eclipse/workspace/projectname. If you run it from inside command console, it will be relative to currently opened folder (even though when you run the code by absolute path!). If you run it by doubleclicking the JAR, it will be relative to the root folder of the JAR. If you run it in a webserver, it will be relative to the /path/to/webserver/binaries. Etcetera.
Always use absolute paths in java.io.File, no excuses.
For best portability and less headache with absolute paths, just place the file in a path covered by the runtime classpath (or add its path to the runtime classpath). This way you can get the file by Class#getResource() or its content by Class#getResourceAsStream(). If it's in the same folder (package) as your current class, then it's already in the classpath. To access it, just do:
public MyClass() {
URL url = getClass().getResource("filename.txt");
File file = new File(url.getPath());
InputStream input = new FileInputStream(file);
// ...
}
or
public MyClass() {
InputStream input = getClass().getResourceAsStream("filename.txt");
// ...
}
Try giving an absolute path to the filename.
Also, post the code so that we can see what exactly you're trying.
When you are opening a file with a relative file name in Java (and in general) it opens it relative to the working directory.
you can find the current working directory of your process using
String workindDir = new File(".").getAbsoultePath()
Make sure you are running your program from the correct directory (or change the file name so that it will be relative to where you are running it from).
If you're using Eclipse (or a similar IDE), the problem arises from the fact that your program is run from a few directories above where the actual source is located. Try moving your file up a level or two in the project tree.
Check out this question for more detail.
The simplest solution is to create a new file, then see where the output file is. That is the correct place to put your input file into.
If you put the file and the class working with it under same package can you use this:
Class A {
void readFile (String fileName) {
Url tmp = A.class.getResource (fileName);
// Or Url tmp = this.getClass().getResource (fileName);
File tmpFile = File (tmp);
if (tmpFile.exists())
System.out.print("I found the file.")
}
}
It will help if you read about classloaders.
say I have a text file input.txt which is located on the desktop
and input.txt has the following content
i came
i saw
i left
and below is the java code for reading that text file
public class ReadInputFromTextFile {
public static void main(String[] args) throws Exception
{
File file = new File(
"/Users/viveksingh/desktop/input.txt");
BufferedReader br
= new BufferedReader(new FileReader(file));
String st;
while ((st = br.readLine()) != null)
System.out.println(st);
}
}
output on the console:
i came
i saw
i left
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.