I am in need of a few special file types for my Spring application hence I raised this specific question on how to do a foolproof file I/O in both my local machine and once the WAR file is uploaded to the server.
I did a few research myself and found some slightly helpful articles:
The question "Absolute file access in Spring Service layer" asks how to do file I/O in a Spring
Serviceclass.The accepted answer suggests to use Spring's
Resourcebut it requires that the files needed to be inside/WEB-INF/classesand unfortunately it contradicts one of the comments with the highest vote-ups:Don't write inside your web content or
WEB-INFfolder. There is no guarantee that the war file will be exploded on the filesystem. Write to a well known (probaly configurable) file location.Okay so where do I put it???
Doesn't matter, find a nice location for your files. Maybe a user directory for your application, inside the TMP directory or whatever you like. Everything but writing inside your
web-appsdirectories.So I guess putting the file in
/srcis okay.The poor guy asked again but this time it needs to be in the Tomcat server: "Tomcat server absolute file access in war webapp".
This answer said to NOT DO FILE I/O INSIDE A
WARFILE.The accepted answer by OP is not helping either because a comment said that:
This solution will not work unless your webapp is deployed as an exploded-
WARfile. It is therefore fragile. Using theClassLoaderorServletContextto fetch resources is a more robust solution. This solution appears to use theClassLoaderbut then mangles the URL and loads the resource using standard file I/O. :(Okay so I saw a link provided by the guy who suggested not to do file I/O in a
WARcalled "How to really read text file from classpath in Java".The problem with this one is that the file needs to be somewhere outside the whole Spring project given by the accepted answer and the second highest suggests
Resourceagain.
What I tried so far
According to DwB's answer, I tried using the ServletContext technique in my Service layer because that's where it's needed (internal computations not appropriate for Controller or DAO). I slipped the following:
private String myFile = null;
protected void init(final ServletConfig config) {
ServletContext context = config.getServletContext();
String contextPath = context.getContextPath();
myFile = contextPath + "resources/test.txt";
}
protected void doGet() {
try {
BufferedWriter writer = new BufferedWriter(new FileWriter(myFile));
writer.append("Lorem ipsum dolor sit amet");
writer.close();
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
I call doGet() in one of my functions but it returned
THE TIME org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [spring] in context with path [/bosom] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException
Why are the codes below not working?
Simple writing
BufferedWriter bw = new BufferedWriter(new FileWriter("/src/resources/test.txt")); bw.append("Lorem ipsum dolor sit amet"); bw.close(); bw.flush();InputStreamworked withBufferedReaderbut now I'm lost withBufferedWriterorOutputStream(source)InputStream is = getClass().getResourceAsStream("/test.txt"); BufferedWriter bw = new BufferedWriter(new FileWriter(is)); bw.append("Lorem ipsum dolor sit amet"); bw.close(); bw.flush();Spring's
Resourceis not helping either (source).I have tried using
resource.toString(),resource.getURI(),resource.getURI().toString(),resource.getURL(),resource.getURL().toString()and still errors and errors.Resource resource = new ClassPathResource("/src/resources/test.txt"); BufferedWriter bw = new BufferedWriter(new FileWriter(new File(resource.toString()))); bw.append("Lorem ipsum dolor sit amet"); bw.close(); bw.flush();It just returns:
java.io.FileNotFoundException: class path resource [src\resources\test.txt] (The system cannot find the path specified) java.io.FileNotFoundException: class path resource [src/resources/test.txt] cannot be resolved to URL because it does not exist java.io.FileNotFoundException: class path resource [src/resources/test.txt] cannot be resolved to URL because it does not existI made an
ENVIRONMENT_VARIABLEinControl Panel >> System >> Environment Variablesand createdmyDatawhich is inD:/resourcesbut the code below is not writing anything to the file (no errors though).File file = new File(System.getenv("myData"), "test.txt"); try { BufferedWriter bw = new BufferedWriter(new FileWriter(file.getAbsolutePath())); bw.write("Lorem ipsum dolor sit amet"); bw.flush(); bw.close(); } catch (IOException e) { e.printStackTrace(); }
Updated based from the current answers
Now I have more questions and doubts than answers because of these. Please note that I intend to do file I/O for a project exported as a WAR file.
Is it possible to do a successful file I/O whilst the project is in the local machine and server (
WARfile)?based from the answers, Yes
If it's possible, in what folder is the most ideal place to put these particular files?
no particular folder was mentioned
What actual function/s should I use to read and write to these files?
???
Here is my Spring application's structure, as seen in Windows Explorer in the Eclipse Workspace (take note):
root
|----> .settings
|----> build
|----> src
|--------> package.name
|--------> resources
|------------> THE_FILES
|----> WebContent
|----> .classpath
|----> .project
Note that I also need the absolute file path in
StringorInputStreamform because I use theweka.core.SerializationHelper'sreadmethod.
I just want to have a solid file I/O that both works in my local machine and even when uploaded as its WAR file in the server (I can feel that's possible).