FileReader throws exception because files path has wrong syntax? - java

I put a file to be read into my resources folder
src
|_main
|_resources
|_graphqls
|_test.graphqls
The following snippet reads the file
final String pathToSchemaFile = this.getClass().getClassLoader().getResource("graphqls/test.graphqls").getFile();
final File = new File(pathToSchemaFile);
this is the result I get when I evaluate the File object returned by .getFile() from the preceding snippet.
file:\C:\maven_repository\com\...\app.jar!\graphqls\test.graphqls
When running the following code new FileReader(file) this exception is being thrown
Method threw 'java.io.FileNotFoundException' exception.
file:\C:\maven_repository\com\...\app.jar!\graphqls\test.graphqls (The filename, directory name, or volume label syntax is incorrect)
java.io.FileNotFoundException: file:\C:\maven_repository\com\...\app.jar.jar!\graphqls\test.graphqls (The filename, directory name, or volume label syntax is incorrect)

You're accessing a file that is actually inside a JAR file (like a ZIP).
If your jar is on the classpath:
InputStream is = YourClass.class.getResourceAsStream("1.txt");
If it is not on the classpath, then you can access it via:
URL url = new URL("jar:file:/absolute/location/of/yourJar.jar!/1.txt");
InputStream is = url.openStream();

You can avoid the file by creating an InputStreamReader.
InputStreamReader reader = new InputStreamReader(
this.getClass().getResourceAsStream("/graphqls/test.graphqls"),
StandardCharsets.UTF_8
);
It is advised to use YourClassName.class.getResourceAsStream() unless you have some specific reason to use the .getClass && .getClassLoader.

Related

The filename, directory name, or volume label syntax is incorrect - how to specify file path in properties file

I am reading properties file to get a file path as below.
String result = "";
InputStream inputStream = null;
try {
Properties prop = new Properties();
String propFileName = "config.properties";
inputStream = GetPropertyValues.class.getClassLoader().getResourceAsStream(propFileName);
if (inputStream != null) {
prop.load(inputStream);
} else {
throw new FileNotFoundException("property file '" + propFileName + "' not found in the classpath");
}
The properties file has the path specified like below.
configSettingsFilePath = C:\\\\ConfigSetting.xml
Now I get this below exception when I run my code saying file is not found.
Creating instance of bean 'configSettingHelper'
configSettingsFilePath = C:\ConfigSetting.xml
2017-09-18 14:47:00 DEBUG ConfigSettingHelper:42 - ConfigSettingHelper :: ConfigSetting File:configSettingsFilePath = C:\ConfigSetting.xml
javax.xml.bind.UnmarshalException
- with linked exception:
[java.io.FileNotFoundException: C:\Java\eclipse\eclipse\configSettingsFilePath = C:\ConfigSetting.xml (The filename, directory name, or volume label syntax is incorrect)]
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:246)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:214)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:162)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:171)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:189)
Instead of reading the path from properties file, if I directly use "C:\ConfigSetting.xml" in the code, it reads the file.
Can you please suggest what I should use in the properties file to specify the path?
Reading the file only fails when the .jar is running.
Running the app from within Netbeans is fine. (Different path)
Also, the path is coming from
URL resourceURL = MyClass.class.getResource("mydir/myfile.txt");
Printing out the path is perfect.
Also, a mypicture.gif in the very same directory loads fine:
ImageIcon mypicture = new ImageIcon(imageURL, description)).getImage();
even when running the .jar. IE: the actual path must be fine.
It is only a text file I try reading via
InputStream input = new FileInputStream(fileName);
is when it fails - and only if it is in the jar.
This is probably because C:\ is not on the classpath. You're using getClassLoader() which presumably returns a ClassLoader.
According to the docs for ClassLoader#getResource:
This method will first search the parent class loader for the
resource; if the parent is null the path of the class loader built-in
to the virtual machine is searched. That failing, this method will
invoke findResource(String) to find the resource.
That file is in the root of the drive, which is not going to be on the classpath or the path of the class loader built-in to the VM. If those fail, findResource is the fallback. It's unknown where findResource looks without seeing the implementation, but it doesn't appear to pay attention to the C:.
The solution is to move the properties file into your classpath. Typically, you'd put property files like this in the src/main/resources folder.

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);

How to create a file from classpath

I'm trying to create a new file in:
project/src/resources/image.jpg
as follows:
URL url = getClass().getResource("src/image.jpg");
File file = new File(url.getPath());
but I get error:
java.io.FileNotFoundException: file:\D:\project\dist\run560971012\project.jar!\image.jpg (The filename, directory name, or volume label syntax is incorrect)
What I'm I doing wrong?
UPDATE:
I'm trying to create a MultipartFile from it:
FileInputStream input = new FileInputStream(file);
MultipartFile multipartFile = new MockMultipartFile("file", file.getName(), "image/jpeg", IOUtils.toByteArray(input));
You are not passing the image data to the file!! You're trying to write an empty file in the path of the image!!
I would recommend our Apache friends FileUtils library (getting classpath as this answer):
import org.apache.commons.io.FileUtils
URL url = getClass().getResource("src/image.jpg");
final File f = new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().getPath());
FileUtils.copyURLToFile(url, f);
This method downloads the url, and save it to file f.
Your issue is that "image.jpg" is a resource of your project.
As such, it's embedded in the JAR file. you can see it in the exception message :
file:\D:\project\dist\run560971012\project.jar!\image.jpg
You cannot open a file within a JAR file as a regular file.
To read this file, you must use getResourceAsStream (as detailed in this this SO question).
Good luck

Load file dynamically from jar

I am trying to read a .json file I am packaging with my .jar.
The problem - finding the file so that I can parse it in.
The strange bit is that this code works in NetBeans, likely due to the way these methods work and the way NetBeans handles the dev workspace. When I build the jar and run it, however, it throws an ugly error: Exception in thread "main" java.lang.IllegalArgumentException: URI is not hierarchical.
My code for getting the file is as such:
//get json file
File jsonFile = new File(AndensMountain.class.getResource("/Anden.json").toURI());
FileReader jsonFileReader;
jsonFileReader = new FileReader(jsonFile);
//load json file
String json = "";
BufferedReader br = new BufferedReader(jsonFileReader);
while (br.ready()) {
json += br.readLine() + "\n";
}
I have gotten it to work if I allow it to read from the same directory as the jar, but this is not what I want - the .json is in the jar and I want to read it from in the jar.
I've looked around and as far as I can see this should work but it isn't.
If you are interested, this is the code before trying to get it to read out of the jar (which works as long as Anden.json is in the same directory as AndensMountain.jar):
//get json file
String path = AndensMountain.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath();
File jsonFileBuilt = new File(new File(path).getParentFile(), "Anden.json");
File jsonFileDev = new File(new File(path), "Anden.json");
FileReader jsonFileReader;
try {
jsonFileReader = new FileReader(jsonFileBuilt);
} catch (FileNotFoundException e) {
jsonFileReader = new FileReader(jsonFileDev);
}
Try
Reader reader = new InputStreamReader(AndensMountain.class.getResourceAsStream("/Anden.json"), "UTF-8");
AndensMountain.class.getResource("/Anden.json") URL when ran outside a jar (for example, when the classes are compiled to a "classes/" directory) is a "file://" URL.
That is not the case when ran from inside a jar: it then becomes a "jar://" URL.
The java.io.File doesn't know how to handle this type of URL. It handles only "file://".
Anyway you don't really need to treat it as a File. You can manipulate the URL itself (either to navigate to a parent directory, for example) or to get its contents (via openStream(), or if you need to add headers, via openConnection()).
java.lang.Class#getResourceAsStream() as I suggested is just shorthand to Class#getResource() followed by openStream() on its result.

Opening a resource file in a servlet on Openshift

I'm in troubles with opening file within my web-app. I tried it locally within Eclipse and it works fine but when I try to deploy it on Tomcat 6 on Openshift it doesn't find resource files for my web-app. There are some txt files in a ProjectFiles directory stored in WEB-INF directory; the code that locally opens file is
String nome_file = "C\:\\Users\\miKKo\\workspace\\fantacalcio_project\\WebContent\\WEB-INF\\ProjectFiles\\Risultati\\risultati_" + nome_lega + ".txt";
BufferedReader reader = new BufferedReader(new FileReader(nome_file));
I've pushed them within Git in the same repository (on server I renamed my project in "ROOT") and I've substituted string with this
String nome_file = this.getServletConfig().getServletContext().getContextPath()+"/WebContent/WEB-INF/ProjectFiles/Risultati/risultati_" + nome_lega + ".txt";
but it doesn't work. I've also tried with a context attribute
/var/lib/openshift/51c6178a5004467630000019/jbossews/work/Catalina/localhost/_/WEB-INF/ProjectFiles
but the thrown exception is always
java.io.FileNotFoundException: (#path) (No such file or directory)
What can I do for this?
Say your file is in the following location:
/WEB-INF/ProjectFiles/Risultati/risultat_text_file.txt
Then using:
String path = "/WEB-INF/ProjectFiles/Risultati/risultat_text_file.txt";
InputStream inputStream = new FileInputStream(this.getServletConfig().getServletContext().getRealPath(path));
Should work for you. Note that, ServletContext.getRealPath() return the real OS path corresponding to the given virtual path.
Edit:
If this doesn't work for your case, you really need to revisit your virtual path. You can manually check that does this file exist in the expected directory in the war file or you can log the output of the getRealPath() method to examine what's really going on! If necessary you can put "/" in your getRealPath() method and examine what is your application's root path.
Since I don't get application's root realpath, I resolved in this way:
String path="/WEB-INF/ProjectFiles/Risultati/risultati_test.txt";
InputStream inputStream = this.getServletConfig().getServletContext().getResourceAsStream(path);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
and now it works. By the way, I also found useful informations here
getResourceAsStream() vs FileInputStream

Categories