FileInputStream vs ClassPathResource vs getResourceAsStream and file integrity - java

I have a weird problem :
in src/main/resources i have a "template.xlsx" file.
If i do this :
InputStream is = new ClassPathResource("template.xlsx").getInputStream();
Or this :
InputStream is = ClassLoader.getSystemResourceAsStream("template.xlsx");
Or this :
InputStream is = getClass().getResourceAsStream("/template.xlsx");
When i try to create a workbook :
Workbook wb = new XSSFWorkbook(is);
I get this error :
java.util.zip.ZipException: invalid block type
BUT, when i get my file like this :
InputStream is = new FileInputStream("C:/.../src/main/resources/template.xlsx");
It works !
What is wrong ? I can't hardcode the fullpath to the file.
Can someone help me with this ?
Thanks

I had the same issue, you probably have a problem with maven filtering.
This code load the file from source, unfiltered
InputStream is = new FileInputStream("C:/.../src/main/resources/template.xlsx");
This code load the file from the target directory, after maven has filtered the content
InputStream is = getClass().getResourceAsStream("/template.xlsx");
You should not filter binary files like excel and use two mutually exclusive resource sets as described at the bottom of this page maven resources plugin

haven't you try accessing it like
InputStream is = new FileInputStream("/main/resources/template.xlsx");
?

Related

how to generate the POI excel file in a specific location?

I have created a java maven programme that generate an excel file using Apache POI API, all is working correctly but when i try to put the report to a specific location doing like this
: FileInputStream inputStream = new FileInputStream(new File("C:\\Users\\C5292600\\Desktop\\report1.xlsx"));
i get the following error :
Exception in thread "main" java.lang.IllegalArgumentException: Invalid char (:) found at index (1) in sheet name 'C:\Users\C5292600\Desktop\repor'
at org.apache.poi.ss.util.WorkbookUtil.validateSheetName(WorkbookUtil.java:151)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.createSheet(XSSFWorkbook.java:873)
at com.occCheckNoData.report.Create.newSheet(Create.java:25)
at com.occCheckNoData.report.mainReport.main(mainReport.java:34)
Is it an existing path? If not use something like File file = new File(yourpath); file.mkdirs(); to create a new path. And to generate the file FileOutputStream fileOut = new FileOutputStream(new File(yourpath + filetype));

java.lang.NullPointerException while getting a filepath in Java (executing through a jar file)

I am getting an NPE at the point of getting path of a File (an sh file in assets folder).
I have tried to read about NPE i detail from the following thread, but this actually could not solve my problem.
What is a NullPointerException, and how do I fix it?
Following is my code snippet:
File absPathofBash;
url = ClassLoader.class.getResource("assets/forbackingup.sh");
absPathofBash = new File(url.getPath());
Later I'm using it in a ProcessBuilder, as
ProcessBuilder pb = new ProcessBuilder(url.getPath(), param2, param3)
I've also tried getting the absolute path directly, like
absPathofBash = new File("assets/forbackingup.sh").getAbsolutePath();
Using the latter way, I am able to process it, but if I create a jar then the file cannot be found. (although the Jar contains the file within the respective folder assets)
I would be thankful if anyone can help me on that.
Once you have packaged your code as a jar, you can not load files that are inside the jar using file path, instead they are class resources and you have to use this to load:
this.getClass().getClassLoader().getResource("assets/forbackingup.sh");
This way you load assets/forbackingup.sh as an absolute path inside your jar. you also can use this.getClass().getResource() but this way the path must be relative to this class path inside jar.
getResource method gives you an URL, if you want to get directly an InputStream you can use getResourceAsStream
Hope it helps!
Since the file itself is in the jar file, you could try using:
InputStream is = this.getClass().getClassLoader().getResourceAsStream(fileNameFromJar);
In case of jar file , classloader will return URL different than that of when the target file is not embedded inside jar. Refer to answer on link which should help u :
How to use ClassLoader.getResources() in jar file
I got it done by creating a temp file. Though it's not difficult, yet I'm posting the code patch here:
InputStream stream = MyClass.class.getClassLoader().
getResourceAsStream("assets/forbackingup.sh");
File temp = File.createTempFile("forbackingup", ".sh");
OutputStream outputStream =
new FileOutputStream(temp);
int read = 0;
byte[] bytes = new byte[1024];
while ((read = stream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
outputStream.close();
}
Now, we have this temp file here which we can pipe to the ProcessBuilder like,
String _filePath=temp.getPath();
ProcessBuilder pb = new ProcessBuilder(url.getPath(), param2, param3)
Thank you everyone for your considerations.
You can use Path class like :
Path path = Paths.get("data/test-write.txt");
if(!Files.exists(path)){
// can handle null pointer exception
}

Read Properties file in java

How do I give absolute path to the properties file.
autoamtion_environment_properties = new Properties();
InputStream iStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(("C:\\automation_environment.properties"));
This is giving a null pointer exception.
If I have this file in project root folder it works, but I need to access it from outside. Any idea what needs to be done?
Thanks.
The file has to be in the CLASSPATH for it to work. Your IDE papers over the difficulty for you, but you'll need to know what you're doing when you don't have the crutch. Include the directory where the .properties files live in your CLASSPATH.
If you know the full path for the file, you can use FileInputStream class
InputStream iStream = new FileInputStream(new File("C:\\automation_environment.properties"));
Otherwise, please refer to this answer https://stackoverflow.com/a/676273/176569
Why not use a FileInputStream instead of all that crazy Thread stuff?
InputStream in = new FileInputStream(new File("C:\\automation_environment.properties"));
http://docs.oracle.com/javase/6/docs/api/java/io/FileInputStream.html
I would try to set \ to / instead like:
InputStream iStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(("C:/automation_environment.properties"));

JAVA: FileInputStream and FileOutputStream

I have this strange thing with input and output streams, whitch I just can't understand.
I use inputstream to read properties file from resources like this:
Properties prop = new Properties();
InputStream in = getClass().getResourceAsStream( "/resources/SQL.properties" );
rop.load(in);
return prop;
It finds my file and reds it succesfully. I try to write modificated settings like this:
prop.store(new FileOutputStream( "/resources/SQL.properties" ), null);
And I getting strange error from storing:
java.io.FileNotFoundException: \resources\SQL.properties (The system cannot find the path specified)
So why path to properties are changed? How to fix this?
I am using Netbeans on Windows
The problem is that getResourceAsStream() is resolving the path you give it relative to the classpath, while new FileOutputStream() creates the file directly in the filesystem. They have different starting points for the path.
In general you cannot write back to the source location from which a resource was loaded, as it may not exist in the filesystem at all. It may be in a jar file, for instance, and the JVM will not update the jar file.
May be it works
try
{
java.net.URL url = this.getClass().getResource("/resources/SQL.properties");
java.io.FileInputStream pin = new java.io.FileInputStream(url.getFile());
java.util.Properties props = new java.util.Properties();
props.load(pin);
}
catch(Exception ex)
{
ex.printStackTrace();
}
and check the below url
getResourceAsStream() vs FileInputStream
Please see this question: How can I save a file to the class path
And this answer https://stackoverflow.com/a/4714719/239168
In summary: you can't always trivially save back a file your read from the classpath (e.g. a file in a
jar)
However if it was indeed just a file on the classpath, the above answer has a nice approach

Access file in jar file?

I need to be able to access a file stored in a compiled jar file. I have figured out how to add the file to the project, but how would I reference it in the code? How might I copy a file from the jar file to a location on the user's hard drive? I know there are dozens of ways to access a file (FileInputStream, FileReader, ect.), but I don't know how to look inside itself.
You could use something like this:
InputStream is = this.getClass().getClassLoader().getResourceAsStream(fileFromJarFile);
If foo.txt was in the root of your JAR file, you'd use:
InputStream is = this.getClass().getClassLoader().getResourceAsStream("foo.txt");
assumes the class is in the same JAR file as the resource, I believe.
You can use getResource() to obtain a URL for a file on the classpath, or getResourceAsStream() to get an InputStream instead.
For example:
BufferedReader reader = new BufferedReader(new InputStreamReader(
this.getClass().getResourceAsStream("foo.txt")));
You could read the contents of a JAR file using the JarFile class.
Here's an example of how you could get a specific file from a JAR file and extract it:
JarFile jar = new JarFile("foo.jar");
String file = "file.txt";
JarEntry entry = jar.getEntry(file);
InputStream input = jar.getInputStream(entry);
OutputStream output = new FileOutputStream(file);
try {
byte[] buffer = new byte[input.available()];
for (int i = 0; i != -1; i = input.read(buffer)) {
output.write(buffer, 0, i);
}
} finally {
jar.close();
input.close();
output.close();
}
Just wanted to add that if we want to access file inside Jar that is located at the following path(only examples as resources loading is OS independent):
Windows:
c:\your-jar-file.jar\dir1\dir2\dir3\foo.txt
Linux:
/home/your-jar-file.jar/dir1/dir2/dir3/foo.txt
Will need to use following code(pay attention that there is NO "/"(forward-slash) character in the beginning of the path):
InputStream is = this.getClass().getClassLoader().getResourceAsStream("dir1/dir2/dir3/foo.txt");
Look at the JarFile class. Everything you need to get the InputStream of a specific entry in the jar file is there.

Categories

Resources