Unable to read input file from bin - java

Errr guys, I wrote some code to read a simple input file in Java, everything works perfectly fine, however after the code is checked-in and when others try to run it, their binary couldn't find the file (eventhough the file is RIGHT THERE in their bin folder)!
java.io.FileNotFoundException: C:\blah\bin\com\common\PackageRFCs.properties (The system cannot find the path specified)
So in my workspace, I have the these structure and files:
com.test.test.java
com.common.Utility.java
com.common.PackageRFCs.properties
In my test.java, I am trying to read the properties file this way:
Class<com.common.Utility> dummy = com.common.Utility.class;
String propURI = dummy.getPackage().getName().replace('.','/') + "/PackageRFCs.properties";
String filepath = ClassLoader.getSystemClassLoader().getResource(propURI).getFile();
...
BufferedReader br = new BufferedReader(new FileReader(filepath));
// do some read line stuff here
The above code work perfectly fine under my Eclipse, but failed when others tried to run it. I thought maybe i had some dangling file in my bin, so i did a Project > Clean, and i am still able to run it perfectly fine... I also tried cleaning the other user's workspace as well, and they still couldn't read the file... WTF is going on?
I can't reproduce the problem on my end.

If you have a URL from getResource() you don't need to convert it to a filepath and open that with a FileReader (which won't work anyway, as the result of URL.getFile() isn't a native file path, it's simply a substring of the original URL). Just use .openStream() or call get{System}ResourceAsStream() in the first place
BufferedReader br = new BufferedReader(new InputStreamReader(
ClassLoader.getSystemResourceAsStream(propURI), "ISO-8859-1"));
(I've assumed ISO-8859-1 encoding because the file is named .properties and this is the standard encoding for Java property files, but if that is wrong then change the encoding to match the file)
But given the structure you've spelled out, it would be more robust to use
Utility.class.getResourceAsStream("PackageRFCs.properties")
which handles the package-to-path mapping for you automatically, as well as being able to handle cases when your classes are loaded by a classloader other than the system classloader.

Related

In what situation is a file placed in the resources of a JAR, but is not accessible in a class' ClassLoader?

I'm just trying to read in a simple .txt file into my java project using this.class.getResourceAsStream(filename). I have several files within main/resources, and almost all of them return an object when I try to get them as an input stream. The only object I can't read in is my text file.
I have placed the file with all of the other resource files that are readable by the classloader, but it appears this file wasn't placed in the class' classLoader for whatever reason. If I unzip the jar, the file is still included with the jar in the same directory as all of the other resources, so it seems to be being built correctly.
I guess what I'm asking is at what point do I tell Java what files I want to be included as a resource in a class' ClassLoader? Is it something that should be done when the jar is built if things are in the correct place (i.e main/resources)?
Here is what the code looks like, and it's respective return values, when running for the file it can find and the file it can't, that are both located in the same place.
// This is not found. Both are placed at src/main/resources
def tmpDict = this.class.getResourceAsStream("dict.txt")
println tmpDict // null
// This is found
def tmpDict2 = this.class.getResourceAsStream("calc.config")
println tmpDict2 // sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream#2dae5a79
Without more info i'd say the path is wrong. when i used just "file.txt" for the path it got NPE
i used this method to read from the stream. The file was located at \src\main\resources\static\file.txt
This worked in eclipse, packaged into jar and worked there too.
public String getFile() throws Exception {
InputStream in = Controller.class.getClassLoader().getResourceAsStream("static/file.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(in, Charset.defaultCharset()));
StringBuilder out = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
out.append(line);
}
return out.toString();
}
Some very Basic checks:
The file must be case-sensitive (as it is not a Windows file), and special characters of the file name might be cumbersome. Also check that the file in your project has the file extension not twice (.txt.txt - Windows hiding the extension).
Check that getResourceAsStream("/a/b/c/A.txt") indeed gives a null.
If not the reading might go wrong on the encoding.

How to read a file that i created inside my the same package?

This is a chunk of data I'd like to access by a method.
I'm doing the following to read my file:
String fileName = "file.txt"
InputStream inputStream = new FileInputStream(fileName);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
My file.txt is in the same package, but I still get FileNotFoundException.
I didn't use a path url to point to the file because I thought since this it going to be an android application, hard-coding the path might not work when deployed... Please correct me if I am wrong. Thanks bunch!
This shows how to do that. https://stackoverflow.com/a/14377185/2801237
Also the 'package' your class is in has nothing to do with the 'path' where the file is being executed from. (two different concepts, 'package' = folder hierarchy of java source code files), 'path' = location on a filesystem of a specific file, your APK is being 'executed' in a particular place, and the location it writes a file is associated with that (I actually don't know where 'offhand' it writes by default, because I always get cache dir, or sd card root, etc.)
You may use:
InputStream inputStream = this.getClass().getResourceAsStream(fileName);

Reading a text file from expected path in java

I want to read a file from directory.File is in root directory. If i use path as E:\Java\Netbeans_practice\project_141\Description.txt then it works fine.But when i wanted to use path as the file name or within a defined folder as Info\Description.txt , it gives error (java.io.FileNotFoundException: Description.txt (The system cannot find the file specified)). Actually i don't want to use the path name before project directory (ex: E:\Java\Netbeans_practice\project_141).I have searched a lot but unable to solve.Please help me. Here is my portion of code :
Scanner in = new Scanner(new FileReader("Description.txt");
while(in.hasNextLine()){
out.print("* "+in.nextLine()+"<br>");
}
When you deploy your web app, only the contents inside the "WebContent" will be deployed. You can verify this by going to (assuming you are using tomcat in your eclipse):
projectworkspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\<contextName>
So you may wanan copy your "Description.txt" file into "/WEB-INF" (for security sake) directory. Then you should be able to access it:
File file = new File(getServletContext().getRealPath("/WEB-INF/Description.txt"));
Update:
String path="/WEB-INF/Description.txt";
InputStream inputStream = this.getServletConfig().getServletContext().getResourceAsStream(path);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));

placing a input file relative to program

In my program (simple plain cosole app) I am reading a file a.txt.
Now I will be giving the program to someone else and he should be able to run it. I don't want the file path to be fixed like D:\a.txt , instead it should be relative to my program. Where should I place the file so that my program always finds it?
File file = new File("D:\aks.txt");
FileReader fileReader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(fileReader);
while( (str= bufferedReader.readLine())!=null){
}
My code is working fine when I hard code the path like D:\a.txt
Put the file in the classpath (e.g. the package root or in a certain package) and just get it straight from the classpath as follows
InputStream input = getClass().getResourceAsStream("/a.txt");
// ... (continue with InputStreamReader and so on)
(the exact path depends on the location of the current class and whether you prefix with / to start from package root and which classloader you're using)
Package and distribute it as a single executabele JAR file.
See also:
Java: Pathnames not working once I export to JAR

Reading File In JAR using Relative Path

I have some text configuration file that need to be read by my program. My current code is:
protected File getConfigFile() {
URL url = getClass().getResource("wof.txt");
return new File(url.getFile().replaceAll("%20", " "));
}
This works when I run it locally in eclipse, though I did have to do that hack to deal with the space in the path name. The config file is in the same package as the method above. However, when I export the application as a jar I am having problems with it. The jar exists on a shared, mapped network drive Z:. When I run the application from command line I get this error:
java.io.FileNotFoundException: file:\Z:\apps\jar\apps.jar!\vp\fsm\configs\wof.txt
How can I get this working? I just want to tell java to read a file in the same directory as the current class.
Thanks,
Jonah
When the file is inside a jar, you can't use the File class to represent it, since it is a jar: URI. Instead, the URL class itself already gives you with openStream() the possibility to read the contents.
Or you can shortcut this by using getResourceAsStream() instead of getResource().
To get a BufferedReader (which is easier to use, as it has a readLine() method), use the usual stream-wrapping:
InputStream configStream = getClass().getResourceAsStream("wof.txt");
BufferedReader configReader = new BufferedReader(new InputStreamReader(configStream, "UTF-8"));
Instead of "UTF-8" use the encoding actually used by the file (i.e. which you used in the editor).
Another point: Even if you only have file: URIs, you should not do the URL to File-conversion yourself, instead use new File(url.toURI()). This works for other problematic characters as well.

Categories