I would like to put ressources in my JAR file but, there is a problem when I want to use it. If I show the path with this code :
JOptionPane.showMessageDialog(null, MyStaticClass.class.getResource("/ressources/") + "file.File" + i, "OK", JOptionPane.INFORMATION_MESSAGE);
File file = new File(MyStaticClass.class.getResource("/ressources/") + "file.File" + i);
The result of messagebox is jar:file:/home/clement/Bureau/Untitled.jar!/ressources/niveau.Niveau1 and the exeption
java.io.FileNotFoundException: jar:file:/home/clement/Bureau/Untitled.jar!/ressources/file.File1 (No file or folder of this type)
The files are in the src folder in src/ressources/file.File1
getResourceAsStream() returns an InputStream. Your code basically tries to find file '/ressources/' which is not a file but a directory, so getResourceAsStream() returns null for it.
There is no point in printing an InputStream. What you could do is something like this:
InputStream is = MyStaticClass.class.getResourceAsStream("/ressources/" + "file.File1")
And then read its contents (for example, using InputStream's read() methods, or wrap it with an InputStreamReader and use it's read(). It's hard to give more advice as I don't know what you'd like to do with what you read.
An update for updated question code follows
getResource() returns a URL instance, which does not suit for printing as well (and for concatenating using + operator). But you can convert it to File instance if you like with help of getFile() method:
File file = new File(MyStaticClass.class.getResource("/ressources/" + "file.File" + i).getFile());
Please also note that getResource() is called on full resource name and not just directory name.
Then you could work with that File instance.
But if you just want to read the resource contents, you could do something like the following (with no need to get URL instance):
InputStream is = MyStaticClass.class.getResourceAsStream("/ressources/" + "file.File1")
Scanner scanner = new Scanner(new InputStreamReader(is, "utf-8"));
try {
if (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
}
} finally {
scanner.close();
}
This example assumes that your file is a text file and has at least one line. It prints that line to the console.
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 want to open a .java text file and insert a new package name at the top of the file. After some research to this I found out that I have to create a new file insert the new Package name and copy everything from my old file. So far so good.
1) 1st Problem either I am not doing it correct, but how am I able to copy line endings in the correct way? I kinda have the feeling that by copying I lose them, not sure but that since I was more focused on my other Problem
2) The file I am trying to rename just doesn't get renamed, therefore resulting in the problem, that all files in which I want to insert the new package are getting named the same and therefore I am left with the last file with the wrong name. Resulting in a loss of all my other files
private static String insertPackage(File file) throws IOException {
//creating package name
File parent = new File(file.getParent());
String packageName = "package " + parent.getName() + ";\n";
//copy old file
File buffer = new File(parent.getPath()+"\\buffer.java");
Charset charset = Charset.forName("UTF-8");
BufferedReader br = Files.newBufferedReader(file.toPath(),charset);
BufferedWriter bw = Files.newBufferedWriter(buffer.toPath(),charset);
bw.write(packageName,0,packageName.length());
String line;
while((line = br.readLine()) != null){
if(!line.startsWith("package ")) {
bw.write(line, 0, line.length());
}
}
//rename new file
// String filepath = file.getPath();
// File rename = new File(filepath);
boolean renamed = true;
if(file.delete()) {
renamed = buffer.renameTo(file);
}
bw.flush();
bw.close();
br.close();
if(!renamed){
return file.getPath();
}
return "";
}
The return value is just there to have a name in case something is failing. So right now everything.
This is just the function to insert the package name, delete the old package name and, copy everything else into the new file. After that it should delete the old file and rename the new one.
You are loosing the line breaks, because readLine strips them, but you never write any out to the file. You will need to add a \n (or \r\n depending on your needs) to every line you write to the new file. You can use BufferedWriter#newLine for writing the platform-dependent line separator.
The new file does not get renamed, because your file streams are still open for both files when you try to rename it. Moreover File#renameTo is highly platform dependent (as noted in the documentation) and might not be able to overwrite existing files, I recommend you switch over to Files#move, where you can specify StandardCopyOption.REPLACE_EXISTING.
I can also recommend to fully switch over to the NIO API and not use java.io.File at all, instead use Path directly
Note also that it is a good choice to use try-with-resources instead of manually closing streams, especially when dealing with multiple streams at once.
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 know this question has been asked many, many times before, but the answers don't seem to help me. Here is my specific issue:
I have a class "TaQL" that accesses two text files from within its void main(String args[]) method. The two text files are in the same package as this class: package "taql". The following code runs fine within Eclipse (Mars) IDE:
String stoplist = TaQL.class.getResource(stoplist).toURI().getPath();
String input = TaQL.class.getResource(input).toURI().getPath();
When I output these two strings I get the correct path to the resource and the code hums along.
However, when I use this method after packaging everything up in a JAR, both strings return "null".
Here is what my code does with each of these text files in the non-JAR version
Get filename string for each text file.
create a new File object from one string and a new FileReader object from the other.
These are fed into a stoplist function and a data input iterator, respectively.
What I really need to be able to do is to seamlessly access these two text files once they are all in a JAR and then use some reference to these to create a File and FileReader object.
Here is some diagnostic code I put in my main method. It will show what the JAR file is seeing as far as files (note that both input and stoplist are filename strings):
System.out.println("intput argument" + input);
System.out.println("Resource path"+TaQL.class.getResource(stoplist));
stoplist = TaQL.class.getResource(stoplist).toURI().getPath();
input = TaQL.class.getResource(input).toURI().getPath();
System.out.println("Path"+stoplist);
System.out.println("Input path" + input);
command line output from running the JAR version of my program (note that this code works perfectly fine when I run from Eclipse)
To actually access the bytes of those files that may be in a jar file you need to use Class#getResourceAsStream(stopList). The URI will give you a path that cannot be used with File or FileInputStream. It's working in your IDE because the IDE has not yet packaged up the files, therefore the #getPath finds an actual file path.
So try this instead:
try (Reader inputReader =
new InputStreamReader(
TaQL.class.getResourceAsStream(input))) {
BufferedReader in = new BufferedReader(inputReader);
for (String line; (line = in.readLine()) != null;) {
// do something with the line
}
}
I have used the Sun File Chooser Demo to choose files from my desktop or any location.
I have added the following code in the open file action:
if (returnVal == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile();
log.append("Opening: " + file.getName() + "." + newline);
ReadData rd = new ReadData(); //added by me
rd.readData(file.getName()); //added by me
} else {
log.append("Open command cancelled by user." + newline);
ReadData class contains readData method which will take the file name and with BufferedReader will read the contents of the file line by line.
But after choosing the file with file chooser it is not able to open the file from my desktop.If I place the file inside the project folder it is able to open the file without any code change.
What modification in code I need to do so that it can choose and open file from any location?
Thanks
You are passing only the file's name, not the complete path, to your ReadData class. So, your ReadData class is not going to know in which directory the file is - it will try to find it in the current directory (whatever that is at the moment).
Instead of just passing the name of the file, pass the whole path:
rd.readData(file.getPath());
Better yet, change your ReadData.readData() method so that it takes a File instead of a String, and pass it the File object that you get back from the file chooser:
rd.readData(file);
getName() only gets the last segment of the file without any path information. If the working directory of your Java application isn't the exact directory that holds that file, that won't work.
Why doesn't your ReadData just take a file? All file input mechanisms built into Java will accept a File (e.g. FileInputStream, FileReader). Otherwise use getPath() I guess.
You are only passing the name of the file to the readData() method.
So if your file is stored at C:\Users\JavaBits\Project\Java\file.txt, your readData() method is only getting file.txt so it can't find the file. You should do this:
rd.readData(file);
This will have the relative path in it.
use file object to open inputstream instead using its name. such as:
BufferedReader br = new BufferedReader(new FileInputStream(file));
modify your method readData to accept File object instead String, and use this object to open BufferedReader.