I am currently working on a Java application in Intellij, and I cannot create a file within my artifact. As an example, I'm using File to create a file within the source, which is MainMenuData.txt.
File mainMenu = new File("MainMenuData.txt");
String absPath = mainMenu.getPath();
mainMenu.createNewFile();
BufferedReader br = new BufferedReader(new FileReader(absPath));
In this, I'm using File to make sure that file exists whenever it isn't.
Instead, I'd like to build within the (Production) artifact. Is that doable?
Anything helps. Thanks.
You could do that.
I assume your artifact is a jar file, which is nothing else than a zip file. You can obtain the location of your jar file in the file system and use the Zip File System to modify it. However I'm not sure, if the jvm might have a problem with that and it might not work on windows, since windows likes to block files, that are in use.
Also this would definitely fail, if your jar file is not stored locally.
A better approach would be to store your data files at the appropriate location in your system.
On Linux(and probably mac): <home>/.local/share/<your application name>/
On Linux(global): /var/lib/<application name>
On Windows(I think, better check it yourself): <appdata>/<your application name>
Your code would look something like this(for Linux):
File home = new File(System.getProperty("HOME");
File configDirectory = new File(home, ".local/share/<application name>");
configDirectory.mkdirs();
File mainMenu = new File(configDirectory, "MainMenuData.txt");
For windows do something similar. If you need both, you should check on which you are currently running.
Related
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"));
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");
I know that there are many questions like this out there, but so far there have been none that have been of help.
In eclipse, I have a file inside of my project folder ,and I can get it to load using:
BufferedReader in = new BufferedReader(new FileReader(new File(path)));
When I export the project it will not load the file because it cannot find the file. I have no idea what is going on. Any suggestions? Thanks.
If you want to read the file, you have two options.
You Could...
Make sure that the file is in the same directory as the exported jar file and/or the same execution context. This will allow you to use something like BufferedReader in = new BufferedReader(new FileReader(new File("./" + fileName)));
When referencing the file, it need to specify a relative path to the file.
This means you must ensure that the file is copied to the correct location when ever you move the jar file.
You Could...
Embed the file within the jar as an embedded resource. This means that the file becomes part of the jar file. This also means that you can no longer reference it as a File, but need to use Class#getResource or Class#getResourceAsStream, for example...
BufferedReader in = new BufferedReader(
new InputStreamReader(this.getResourceAsStream("/path/to/resource")));
In order to use this, the file must be placed within the resources directory within your Eclipse project and the directory included within your build path
If you want to be able to write to the file, then you MUST use option one. Embedded resources can not be written to (without a lot of work)
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
I'm working with text files on Java. On Ubuntu 10.
But, I'm having problems with path dir.
Example:
saveFile("textFile.txt","abc");
This abstract function basically put "abc" on "textFile.txt".
I compile this file, and create a jar file (using NetBeans).
When I run the app, and call saveFile("textFile.txt","abc"), textFile.txt is saved on \home. I don't want this. I want that textFile.txtgo to pathDir inside jar file.
How do I write in this file, this same way?
When reading resources from a JAR file, you cannot use the File API. Instead, you use Class.getResourceAsStream(), like this:
reader = new InputStreamReader(MyClass.class.getResourceAsStream(
"/apathdir/textFile.txt"), "UTF-8");
Note also how the encoding is specified. FileReader does not allow that, which is why it should usually be avoided.
Iwant to know, if fileName =
"textFile.txt", what is the path dir
of this file?
If you only use a bare file name (without giving a directory), the JVM will look for the file in the current directory of the JVM process; that is usually the directory you ran the JVM (the java executable) from.
how do i do to set
/apathdir/textFile.txt?. apathdir is a
directory that is inside jar file.
I tried: fileName = "/apathdir/textFile.txt", but doesn't works.
If you want to load a file from inside a JAR file, you cannot load it using FileReader. You need to use ClassLoader.getSystemResourceAsStream() (or Class.getResourceAsStream). See e.g. this article for an explanation:
http://www.devx.com/tips/Tip/5697