I've a resource folder(files) in my java swing project which contains a text file (users.txt), I'm reading and writing data into that text file.
When i export it as jar file, reading from that file is fine, but writing in the file is problem.
I'm reading from file this way
InputStream in1 = getClass().getResourceAsStream("/files/users.txt");
BufferedReader reader1 = new BufferedReader(new InputStreamReader(in1));
Reading is perfectly working fine in jar file
and writing in the same file below code(which is problem for jar file)
File file = new File("src/files/users.txt");
FileWriter fw = new FileWriter(file,true);
fw.write(data+"\n");
fw.close();
please help me out how can i write into the file in resource folder using jar file.
Thanks!
As the comments already say, files in the JARs are considered read-only.
You have to create a file at some user or installation directory based location (or a location chosen by the user).
If you have pre-configured data you have at least 2 options:
Ship the file along the JAR file using some kind of packaging tool (can also be a ZIP file). For ZIP files have a look at the Maven Assembly Plugin, if you're using Maven.
Extract the file from the JAR.
For the latter use case I've written some utility classes:
public void extractResource(String resourcePathString, Path targetDirPath) throws IOException, URISyntaxException {
URI jarURI = JarFiles.getJarURI(SomeClassInTheJar.class);
try (FileSystem jarFS = JarFiles.newJarFileSystem(jarURI)) {
Path resourcePath = jarFS.getPath(resourcePathString);
CopyFileVisitor.copy(resourcePath, targetDirPath);
}
}
With the help of CopyFileVisitor you can easily recursively extract/ add directories from/ to JAR or ZIP files, as CopyFileVisitor uses PathUtils and thus works across file systems.
JarFiles.getJarURI gets the JAR URI of a class.
For more information have a look at the tutorial: https://www.softsmithy.org/softsmithy-lib/lib/2.1.1/docs/tutorial/nio-file/index.html#ExtractJarResourceSample
The library is Open Source. You can get it from Maven Central:
<dependency>
<groupId>org.softsmithy.lib</groupId>
<artifactId>softsmithy-lib-core</artifactId>
<version>2.1.1</version>
</dependency>
Related
I am trying to export a jar file using eclipse but it doesn't include any folder or file outside the src. I have an images folder and 2 csv files that I need to be in the jar file so the images can be displayed and for the csv files to be loaded. When I run in eclipse the images are displayed and the csv files are loaded but when I export as jar file they don't.
background.setIcon(new ImageIcon("images\\marvel_800_500.png"));
This is how I'm setting the images
public static void loadAbilities(String filePath)
.
loadAbilities("Abilities.csv");
How can I include the folder/files in the jar file or load them in any way?
Java Project
try (BufferedReader br = new BufferedReader(
new InputStreamReader(getClass().getResourceAsStream("/resources/foo.csv")))) {
// Code here
}
Is the correct way to read a resource with a BufferedReader
I am writing a Spring Boot web app.
In my app I need to be able to download a zip file that is packaged into the executable application .jar.
I am using ClassPathResource to load the stream of that file:
Resource applier=new ClassPathResource("applier/com.itnsa.patch.applier-1.0.25-SNAPSHOT-package.zip");
if (applier.exists()) {//do stuff}
The zip file is located in /src/main/resources/applier.
In some other classes of my app I already use this method to retrieve some .txt files from /src/main/resources/exception and everything works correctly. When I try to access the zip the exists method returns false.
What am I doing wrong in accessing the zip archive? How can I achieve this?
Resource applier=new ClassPathResource("applier/com.itnsa.patch.applier-1.0.25-SNAPSHOT-package.zip");
if (applier.exists()) {//do stuff}
It should work, i tried same file name and same folder structure it returns true, Make sure that jar file is on class path.
If you are doing/working it with any IDE make sure jar file is on classpath.
There is also another way you can utilize given below, but this is not the case for you
InputStream in = getClass().getResourceAsStream("/fileName.zip");
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
I have an executable JAR that has a file in it that i want to open as a java.io.File instance from code (not InputStream or anything else...just File).
Its a maven project and the file is at the root of "src/main/resources/file.xxx"
The file is located at the root directory of the jar after packaging(verified that its there).
My first attempt: FileNotFoundException
java.io.File myFile = new java.io.File("file.xxx");
someMethodThatUsesTheFile(myFile); //I really need it to be a file!!!
Other attempts: FileNotFoundException
java.io.File myFile = new java.io.File("/file.xxx");
java.io.File myFile = new java.io.File("classpath:file.xxx");
java.io.File myFile = new java.io.File("classpath:/file.xxx");
I am not sure whats really going on. Web Apps can easily just load everything from the webapp root directory, Im confused as to why JAR apps behave differently.
Additional Info:
Using Java8 as runtime/build
command to run the JAR: "java -jar myjar.jar"
Application Code and file are both located in the same jar
Short Answer: It is not a "File", so you just cant do it.
The JAR file is a File, but not its contents.
Alternatives would be:
Try other overloaded versions of that method, InputStreams are
usually your options, you can load it using this code:
InputStream is = getClass().getResourceAsStream("file.xxx");
Move that file out of the JAR and into the same directory of the JAR (consider the security risks)
Try this one may help you :
URL url = this.getClass().getResource("src/main/resources/file.xxx");
File file= new File(url.toURI());
I'm tried several ways to zip a directory structure in a zip file with Java. Don't matter if I use ZipOutputStream or the Java NIO zip FileSystem, I just can't add empty folders to the zip file.
I tried with unix zip, and it works as expected, so I discarded a possibly zip-format issue.
I could also do a little workaround, adding an empty file inside the folders, but I don't really want to do that.
Is there a way to add empty folders in zip files using java API's?
EDIT: Based on answers and comments, this is pretty much the solution I got.
Thanks!
Java NIO makes this as easy as working with a normal file system.
public static void main(String[] args) throws Exception {
Path zipfile = Paths.get("C:\\Users\\me.user\\Downloads\\myfile.zip");
try (FileSystem zipfs = FileSystems.newFileSystem(zipfile, null);) {
Path extFile = Paths.get("C:\\Users\\me.user\\Downloads\\countries.csv"); // from normal file system
Path directory = zipfs.getPath("/some/directory"); // from zip file system
Files.createDirectories(directory);
Files.copy(extFile, directory.resolve("zippedFile.csv"));
}
}
Given a myfile.zip file in the given directory, the newFileSystem call will detect the file type (.zip mostly gives it away in this case) and create a ZipFileSystem. Then you can just create paths (directories or files) in the zip file system and use the Java NIO Files api to create and copy files.
The above will create the directory structure /some/directory at the root of the zip file and that directory will contain the zipped file.
Been looking for this for the past 2 hours and can't find anything (I've found solutions to the same problem but with images, not text files).
Pretty much, I made a program that reads a text file. The file is a list of names and IDs. Using Eclipse, I put the file in my src folder and in the program put the path file to it. Like this:
in = new BufferedReader(new FileReader(curDir+"\\bin\\items.txt"));
Where curDir is the user's current directory (found with System.getProperty("user.dir")).
Now, problem is, the program runs fine when I run it from Eclipse, but when I try to make it a runnable JAR and then run it, the program runs, but the info from the text file does not load. It look like Eclipse is not putting the text file with the JAR.
EDIT: Solved-ish the problem? So the JAR file needs to the in a folder with all the original files? I am so confused, what is a JAR file then?
A more robust way to get a file whether you are running from Eclipse or a JAR is to do
MyClass.getResource("items.txt")
where MyClass is a class in the same package (folder) as the resource you need.
If Eclipse is not putting the file in your JAR you can go to
Run -> Run Configurations -> -> Classpath tab -> Advanced -> Add Folders
Then add the folder containing your file to the classpath. Alternatively, export the Ant script and create a custom build script.
To the point, the FileReader can only read disk file system resources. But a JAR contains classpath resources only. You need to read it as a classpath resource. You need the ClassLoader for this.
Assuming that Foo is your class in the JAR which needs to read the resource and items.txt is put in the classpath root of the JAR, then you should read it as follows (note: leading slash needed!):
InputStream input = Foo.class.getResourceAsStream("/items.txt");
reader = new BufferedReader(new InputStreamReader(input, "UTF-8"));
// ...
Or if you want to be independent from the class or runtime context, then use the context class loader which operates relative to the classpath root (note: no leading slash needed!):
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("items.txt");
reader = new BufferedReader(new InputStreamReader(input, "UTF-8"));
// ...
(UTF-8 is of course the charset the file is encoded with, else you may see Mojibake)
Get the location of your jar file
Firstly create a folder(say myfolder) and put your files inside it
Consider the following function
public String path(String filename)
{
URL url1 = getClass().getResource("");
String ur=url1.toString();
ur=ur.substring(9);
String truepath[]=ur.split("myjar.jar!");
truepath[0]=truepath[0]+"myfolder/";
truepath[0]=truepath[0].replaceAll("%20"," ");
return truepath[0]+filename;
}//This method will work on Windows and Linux as well.
//You can alternatively use the following line to get the path of your jar file
//classname.class.getProtectionDomain().getCodeSource().getLocation().getPath();
Suppose your jar file is in D:\Test\dist
Then path() will return /D:/Test/dist/myfolder/filename
Now you can place 'myfolder' inside the folder where your jar file is residing
OR
If you want to access some read-only file inside your jar you should copy it to one
of your packages and can access it as
yourClassname.getResource("/packagename/filename.txt");