Runnable Jar File with extra .txt - java

I have built my GUI program and got a runnable jar file but I want to include a txt file that can be edited by the user to the jar file or accompanied with it. this text file can contain a path of an editor that is different between operating systems. Is there a way to do that?
thanks

you cant edit a file and save it inside the jar. what you can do is include your file in the jar with a default data, edit it and save it to a file outside the jar.
actually it is possible if you open the jar itself with the code, and repack it when you change the text, but its like disassemble a car doors, wheels, seats and engine just to put something in the glove box

The simplest way is to place the .txt (eg. file.txt) file by the jar, i.e., you can access it in your Java code:
File file = new File("file.txt");
In another way, if you want to launches the associated editor application (default for that file type in the current OS) for editing, you can try the next:
File file = new File("file.txt");
if (Desktop.isDesktopSupported()) {
Desktop.getDesktop().edit(file);
}

Related

How to read a file from a different folder than the project

I'm trying to read a txt file that is in a folder called "levels". The class where I'm using the Scanner is in src/anotherPackageName, if that's relevant. When I execute:
Scanner s = new Scanner(new File("levels/level0")); //adding .txt doesn't fix
it throws an exception. I don't want to use an absolute path, but rather relative to the project if possible. This is my folder structure:
D:\OneDrive\Folder\AnotherFolder\ProjectName
ProjectName
src
packageOne
ClassWhereImUsingScanner
OtherClasses
(...)
levels
level0
level1
(...)
So in order to access a file you could do something like this:
FileReader sourceFile = new FileReader("levels/level0.txt");
BufferedReader inStream = new BufferedReader(sourceFile);
String Line = inStream.readLine();
Then, you can use a tokenizer depending on your data and how you want to store it.
You could see this example: http://www.mkyong.com/java/how-to-read-file-from-java-bufferedreader-example/
Bear in mind that in most Java code, the end state of the project is not run from the IDE, but rather from some production system (e.g. an app or a server). In that case, your development source code structure won't be available.
There are two main ways to read text files or other resources in Java: either you can find the path to the actual file, in which case you need to deal with possibly not running out of your development source tree, or else you need to find a way to bundle the text file into your project.
Most Java projects end up getting compiled into some kind of archive, either a JAR file or a WAR file (for web applications) or something like an Android APK. In most cases you can add your own text files into the project archive. (For example, in a Maven project, if you just put your text file in the src/main/resources folder it should be included in the compiled JAR.)
However, in this case, the text file is no longer a separate file on disk, but rather a blob of data inside an archive. You could unzip the archive to get an actual File object, but that's wasteful if all you actually need is to read the bytes.
Thus, the most common way that text files like this are read is by using the existing ClassLoader mechanism, which is what is reading the .class files from disk (or from an archive, or over the network, or whatever). The ClassLoader already knows how to load bytes that are "alongside" your compiled code, so you can just make use of that.
In your case, you should be able to do something like this:
Scanner scanner = new Scanner(
getClass().getResourceAsStream("/path/to/file.txt"));
In this case, the /path/to/file.txt path is relative to the path your class was loaded from. E.g. if your class is named my.package.Foo then the actual class bytes will be in a folder (either a filesystem folder or in a JAR file or something) named my/package/Foo.class -- in this case, the path/to/file.txt and my/package/Foo.class will be relative to the same root.
See the documentation on resources for more information.
Usually the path is relative to your execution, but it also depends on your project setup on eclipse, could you send more information about you directory structure?
Based on you structure try something like this:
Scanner s = new Scanner(new File("../levels/level0"));

Passing a .JAR program (ran from terminal) a text file as input

I have created a java program that other testers will use to help with their testing. I will be sending them a zip file with the .jar, a readme.txt, and main.properties.txt file.
The main.properties.txt file is a template for the testers to input their DB access credentials. They will update the main.properties file with their db cred's and then attempt to run the .jar from the terminal or command line. The issue I am running into is this. My program needs this updated main.properties.txt file so it can create the connections to our DB's.
What instructions do I need to give in my readme so my program can successfully find the main.properties.txt? Does the main.properties need to be in the same directory as the .jar? Can the testers just create a file on their desktop or documents folders to put the .jar and main.props?
The other question I have is how do I pass this file to my program once its ran from the terminal? Currently it is really easy, because the main.props is part of my program and I can just do something like
Properties prop = new Properties();
FileInputStream in = new FileInputStream("src/main/resources/main.properties");
prop.load(in);
in.close();
But now main.properties is not part of the project anymore. I don't know how to change the code above so that it can find the text from a directory on the local. The location in which they wish to put their main.properties is out of my control so writing a static path will not work. Please help!
There are many ways, I'll show you two.
You need a File object that points to the main.properties file. Then you create a stream on this object new FileInputStream(File) , as you already did by using a String.
The problem of course is to get a relative path to main.properties.txt which works on all systems, regardless where the jar-File is located.
1. Desktop
In this case the main.properties.txt is located at the users desktop. Here is how you access it:
File desktop = new File(System.getProperty("user.home"), "Desktop");
File target = new File(desktop, "main.properties.txt");
Alernativly, if you plan to distribute configuration and property files that do not require user interaction, you may want to use locations like Temp or Documents (Windows).
2. Relative to the jar
Probably one of your best options. Assume the target is in the same folder than the jar-File (or at least in a fix structure relative to the jar). Here is how you access it (related question: how-to-get-the-path-of-a-running-jar-file):
CodeSource codeSource = YourMainClass.class.getProtectionDomain().getCodeSource();
File jarFile = new File(codeSource.getLocation().toURI().getPath());
File jarDir = jarFile.getParentFile();
File target = new File(jarDir, "main.properties.txt");

Reading text file from outside a JAR file?

I am able to read and alter a text file whilst in Eclipse, however when exported as a "Runnable JAR" it no longer works, it seems to me that the relative path is from inside the JAR, not to the JAR.
BufferedReader bufferedReader = new BufferedReader(new FileReader("RELATIVE PATH"));
I want it so that if I export my program as program.jar, and have file.txt in the same folder as program.jar, it opens file.txt if that is the relative path set.
Thanks for any help.
You can fetch the directory of your .jar file according to the solution of this answer and make your file accesses relative to that directory.
Beware of the warning concerning loading your class from a non-file location!

Creating and executable JAR file that uses an external XML file

I have a java application in Eclipse that uses an eml file like so
File matches = new File("matches.xml");
The file is located in the default package as all the other classes. When I create the JAR it bundles in the XML file with it. My application require me to be able to make changes to the XML file. How can I set it up so the JAR can reference the XML file outside of itself?
My application require me to be able to make changes to the XML file.
Then you will need to extract it from the Jar and save it somewhere on the local file system.
See How can an app use files inside the JAR for read and write? for more details.
If you're using new File("matches.xml") that won't use a file within a jar file at all. It will only look on the external file system.
If you need to be able to use an external file if it's present, or the version in the jar file as a fallback, you'll need to test for the file's existence (File.exists()) and use Class.getResourceAsStream("matches.xml") for the fallback behaviour.
As you want to keep the file outside the jar and want to update it so the jar can read, so you can put the file in the same directory where the jar is and use the following code to access the file
FileInputStream file = new java.io.FileInputStream("matches.xml");
So this can be the directory structure.
- matches\
- matches.jar
- matches.xml

Eclipse-Java: where to put file for Read purpose

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

Categories