I have a Java project which has this file structure (shown in Eclipse):
ProjectName
+- Deployment Descriptor: ProjectName
¦- Java Resources:src
¦- Package1
-MyClass.java
¦- FileFolder
-MyFile.txt
And so far from myClass I'm able to read MyFile.txt using:
try
{
reader = new BufferedReader(new FileReader(new File("FileFolder/MyFile.txt")));
while((line=reader.readLine())!=null)
{
line=line.trim();
myVector.add(line);
}
reader.close();
}
catch(Exception e)
{
e.printStackTrace();
}
But when I put Package1 into a Dynamic Web Project AND the FileFolder folder in root, the file is no longer found.
Does anyone know how to read the file?
Thanks in advance!
Dynamic Web Projects generate WAR files.
The server may or may not expand the WAR file back to a file system structure.
You're best off using the Class or ClassLoader .getResourceAsStream("/FileFolder/MyFile.txt") which can read files from JAR/WAR files, and returns an InputStream.
Example:
reader = new BufferedReader(new InputStreamReader(this.getClass().getResourceAsStream("/FileFolder/MyFile.txt")));
Edit: If this is from a Servlet, consider using gawi's answer instead.
Edit 2: If this is in a static method, you'll need to use MyClass.class instead of this.getClass(), where MyClass is the class name.
You are opening a file using a path relative to the current working directory. That's not likely to work on a web app container because the current working directory will not be the root of your application.
Furthermore, you file might not be on the file system but rather in a WAR file.
The proper way to open a file in a webapp is to use the ServletContext.getResourceAsStream() method.
Related
I have a maven project and need to write JSON objects in file.json that should be located in
src/main/resources/
But before I need to check if file exists. If not than create it.
public static void writeMenuJSon(String jsonParamIn) {
JsonParser parser = new JsonParser();
JsonObject modulJson = parser.parse(jsonParamIn).getAsJsonObject();
//TODO check if file exists and create file if not
code here ...
// write to file JSON object
try (Writer writer = new FileWriter("path to file")){
Gson gson = new GsonBuilder().create();
gson.toJson(modulJson, writer);
} catch (IOException e) {
e.printStackTrace();
}
}
Something is totally wrong if you are creating dynamically file in src/main/resources This is only going to work in your development environment. When you deploy your code using Jar or War there won't be this directory on file system. It will be contained within Jar / War or other packaging.
If you understand above and still want to do it. Go related to your current working directory to create file, Usually the working directory when you launch your Main from IDE is setup to root of project so create a file at
src/main/resources/foo.txt
will do it. Alternatively you can figure out your current working directory from your IDE launcher or at runtime using
System.getProperty("user.dir");
What are you exactly trying to achieve writing the JSON file to the mentioned directory ?
I might miss something important in your question but:
it is possible to create code that does this thing but i'm not sure at all how are you going to run this code and is it sane solution to your problem?
When you mvn package the project name P having this "src/main/resources/" resources there will be added to package P.war/.jar or so but there will not be any JSON-file in directory until you run the code - this code you are after - that generates it and it is not done without some -maybe ugly- extra job.
If you have this code included in this project it will be run only when the project package is run. And there will not be this "src/main/resources/" where to write it.
I have a simple java web application with following folder structure.
When I deploy the web app it has data.json file in WEB-INF/classes folder. I need to write data to this file from controller.java class controller package which is in WEB-INF/classes folder.
I tried following code.
FileOutputStream output = new FileOutputStream("..\\data.json", true);
output.write(jsonObject.toJSONString().getBytes());
output.flush();
This doesn't give me any error which suggest that the operation happen in a file somewhere in my computer.
How can I write to the data.json file? I can't give absolute path here.
WEB-INF/classes is for the class-path. Files there should be considered read-only, cacheable resources (getResource, getResourceAsStream).
The HttpRequest.getServletContext().getRealPath("/WEB-INF") can be used,
for file system paths.
I suggest using the classes files as template, copied the first time to a real file system path, and then being overwritten.
Use /, not Windows \\.
Use close() and then flush() is not needed.
Use getBytes(StandardCharsets.UTF_8).
Following code worked,
FileOutputStream output = new FileOutputStream( request.getSession().getServletContext().getRealPath("WEB-INF/classes/data.json"), false);
This is the content of my netBeans project:
To use the folder called "ErrorSet" i use this line:
File file = new File("ErrorSet/error_list.xml");
It is necessary to import this file because it contains custom error codes, to the point:
When you want to import something in a netbeans project, the default "root" from where you use the files is the project name folder like [projectName]/ErrorSet/error_list.xml ...
Where do i need to place the ErrorSet folder when deploying the [projectName].war from dist folder in tocmat7 so that i can use new File properly? What does the File("ErrorSet/error_list.xml") parent directory become since its in tomcat7?
Keep in mind that Web Pages and Source packages are different things.
To use the classes inside Source packages with custom files, you have to place your files inside a Package and use getClass().gerResource() like this:
In case the ErrorSet folder is a folder inside another package use this:
File file = new File(getClass().getResource("ErrorSet/error_list.xml").toURI());
And if the error_list.xml is in the same package as the class, simply use getResource("error_list.xml").
Don't use java.io.File.
Instead, use a stream that you can get from the ClassLoader, like this:
InputStream in = null;
try {
in = request.getServletContext().getResourceAsStream("/WEB-INF/ErrorSet/error_list.xml");
if(null != in) {
// read the XML
}
} finally {
if(null != in) try { in.close(); }
catch (IOException ioe) { /* log this */ }
}
Now, put your file into /WEB-INF/ErrorSet/error_list.xml in your deployment.
This will work whether the file is on the file system or packaged up in an unexploded WAR file. It will also work in environments with a SecurityManager installed that won't allow the web application to read files, because the servlet container probably does have privileges to read those files.
I have a file holding default information that I use to load the textFields of my application. I looked up how to get this built into my jar file when I build and I was told to put it in the source packages and it would be brought along, so I have done that.
File Structure:
Project
-Source Packages
-src
~Java Classes
-defaultFiles
~Defaults.txt
The code I am trying to use is this:
BufferedReader in;
try {
URL resourceURL = FuelProperties.class.getResource("/defaultFiles/Defaults.txt");
in = new BufferedReader(new FileReader(resourceURL.getPath()));
}
And this works perfectly when I run it through NetBeans but when I build the project and try to run it from the jar file it is not grabbing the file.
I have verified that the default file is being built and exists in the same file structure shown above.
If you can help me out with this I would be extremely grateful as I have no idea what is keeping this from working. Thanks.
You have to lookup in the classpath, not on the disk.
The API to use is :
URL resourceURL : this.getClass().getResource("relative path in the classpath");
Once you have the url you can open a stream, etc.
EDIT : in the main method, you of course need to replace
this.getClass()
by
ClassName.class
I found the answer after searching through a couple dozen questions. It turns out that you can only get a InputStream of the data within a file within your JAR not a File object like I was attempting to do.
(If you want the File object you just have to extract the files from the JAR in your program and then you have access to it.)
So the code that got my problem to work was simply replacing this:
URL resourceURL = FuelProperties.class.getResource("/defaultFiles/Defaults.txt");
in = new BufferedReader(new FileReader(resourceURL.getPath()));
With this:
in = new BufferedReader(new InputStreamReader(this.getClass().getResourceAsStream("/defaultFiles/Defaults.txt")));
And now it is working both inside NetBeans and in the Built JAR file.
I'm programming Java in Eclipse IDE. Here is code I want to read file:
File file = new File("file.txt");
reader = new BufferedReader(new FileReader(file));
I put file.txt in two place:
1) same folder of this SOURCE file.
2) in bin\...\ (same folder of this CLASS file)
But I allways receive NO FILE FOUND.
Please help me.
thanks :)
If the file ships with your application, it would be better accessed as a resource than as a file. Simply copy it to somewhere in your build path and use Class.getResourceAsStream or ClassLoader.getResourceAsStream. That way you'll also be able to access it if you bundle your app as a jar file.
Currently, you're looking for the file relative to the process's current working directory, which could be entirely unrelated to where the class files are.
if you put the file under sources and inside the package "test" for example, the path is:
./src/test/file.txt
you can use
File file = new File("./src/test/file.txt");
System.out.println(file.exists());
The path ./bin/test/file.txt will work in the second case and is more suitable for a normal java project