Creating or reading files on any computer - java

my program on startup will:
1. search for a file
2. read the file
3. and set a string to the files contents
But the way ive done it it will only work if they have the exact path that i am hard coding in.
i want the path to adapt to other computers. I think i should use the Path class but ive just heard about that so not sure where to go.
basically i want it to search for a file on any users desktop, and if its not there make it.
if you need some code to clarify i can post it just let me know

I could think of two options.
You can simply specify a file name such as "myFile.txt", so the program will search this file in its program/project folder.
If it does not exist you can write the code to create it in the program folder, instead of hard coding any absolute path.
Else, you can try using the javax.swing.JFileChooser class to pop up an Open and Save dialog box.
This will give the end-user the freedom to select any file for reading and writing.
I found below two articles with some example on how to use the class. Please refer them for more information.
https://www.codejava.net/java-se/swing/show-save-file-dialog-using-jfilechooser
How to "Open" and "Save" using java
Thanks.

You can use the path "./yourfile.txt". It will search for "yourfile.txt" in the directory ".". That means the project's current directory. Maybe it can help you.

Related

Read a file from same folder as JAR file but still read resources folder when loading from IDE

I've been trying to make jar application that can read a csv file in the same directory as it. This is, however, proving difficult as my means for accessing the file currently is:
InputStream is = getClass().getClassLoader().getResourceAsStream(filename);
Which works for my program running in the IDE and for my tests but doesn't work when I run the program from the compiled jar file. I have no idea how to get it to work for both. I seriously can't understand this path stuff, it seems like there are a million ways to do it and only one of them work for only one specific scenario.
I've been trying to make jar application that can read a csv file in the same directory as it.
Ah, there's your problem. That just isn't a thing.
There are only 2 types of files:
Application Resources
These are read only, and are as much part of your app as your class files are. It is not in any way relevant to think about 'editing' them - that's not the kind of thing they are. It is reasonable to assume that if this resource is somehow missing, the app is as corrupt / misinstalled as it would be if class files are missing.
For this, you use .getResource and .getResourceAsStream. And note that getClass().getClassLoader() is wrong, you want MyClass.class.getResource and then add a slash if you want to go from root (because getClass() potentially breaks when you subclass, and going via classloader is [A] just typing for no reason, and [B] breaks in bootload scenarios. MyOwnClassName.class.getResource never breaks, so, always use that).
This asks java to look in the same place class files are and nowhere else. Your class files are inside the jar files, and not next to them, therefore, it won't find a text file that is sitting next to jar files.
it does not make sense that it does work during development: That means you shoved a file inside the resources folder, which is equivalent to having a CSV file inside the jar file. You must have gone out of your way to tell your build system to do weird things. Don't do that.
If that CSV file is not intended to be user editable it should be inside the jar file and not next to it: That makes it an application resource. Examples of application resources:
You have a GUI, and you need to store the icon files and splash screen art and such someplace.
You ship static data with your app, such as a table of all US states along with the zipcodes they use (could be a text or csv file for example).
Templates of config files. Not config files themselves.
DLLs and the like that you need to unpack (because windows/linux/mac isn't going to look inside jars for them).
You're a webapp and you want to ship the HTML static files along with your webapp.
If this is what your CSV file is, the fix is to put it in the jar, not next to it, then load it with MyClass.class.getResource(name).
Config files and project files
For example:
For a rich text editor (like, say, LibreOffice Writer), the .odt files representing your writings.
Save games for a game.
A config file, which can be edited by the user, or is edited by your own app in a 'preferences' dialog. This stores for example whether to open the app full screen or not, or authentication info for a third party API you're using.
These should not be in the jar, should not be loaded with .getResource at all, and should not be in src/main/resources in the first place.
They also should not be next to your jar! That's an outdated and insecure model (the idea that editable files sit in the same place the app itself sits): A proper OS configuration means that an app cannot write to itself which is most easily accomplished by having it be incapable of writing to its directory. Some OSes (notably, windows) did this wrong for a while.
For example on windows, your app lives in C:\Program Files\MakorisAwesomeApp\makori.jar, and the data files for it live somewhere in C:\Users\UserThatInstalledIt\Documents\MakorisAwesomeApp.
oh linux, your app might be /usr/bin/makori and the data lives somewhere in the home dir. Config data might live in /etc/.
You don't "ship" your config files, you instead make installers that create them. You can do this part in-app by detecting that the relevant config file does not exist, load in a template (that is a resource, shipped inside your jar, loaded with getResource), and write it out, and tell the user to go look at it and edit it.
I really want a CSV file next to my jars!
Well, that's wrong, so, there are no libraries that make this easy. When you want to do silly things its good that APIs don't make that easy, right?
There are really hacky ways to do this. You can use .getResource to get a URL and then 'parse' this. This breaks the classloader abstraction concept (because in java, you can write your own classloaders and they can load from anywhere, not just files or entries in jars), but you can ask for 'yourself' (MyClass.class.getResource("MyClass.class")), pull the URL apart and figure out what's happening - does it start with file://? Then it is a file, so turn it into a j.i.File object, and go from there. Does it start with jar://? find the !, substring out the jar part, and now you know the jar. Make that a java.io.File, ask for the parent dir, and look there for the CSV.
You have to write all this. It's complicated code that is hard to test. You should not do this.

Write to ~/Library/ApplicationSupport/* with java?

I'm writing an Application for Mac in Java that needs to store a few preference files. By default, they seem to be storing to the User folder, but I'd like to store the files in the Library/ApplicationSupport folder, but I can't seem to figure out how to do that.
I've tried File file = new File("/Library/ApplicationSupport/AppName"); then file.mkdir() but it keeps returning false. I've tried adding ~ to the front of /Library/, and that didn't work either.
I've also tried just writing the file to the desired directory on a FileOutputStream, but no luck there either. I'm open to other ways of storing my preference files, I just don't want them stored in an obtrusive way to the user.
Thanks!
You can't write to /Library/ApplicationSupport because your user would not have the permission.
The plain Java io classes don't understand "~", so to write to ~/Library/ApplicationSupport, you need:
System.getProperty("user.home") + "/Library/ApplicationSupport"

Saves game level settings

I have been coding for about a month and I have found ways to adapt around ever problem but one. The problem as you can probably see by the title is how to make a way to make game saves. I am currently creating a very simple game that has about 5 classes of my code and maybe 2 of Java Swing GUI.
I know how I would like to go about the saving process but I have no idea how to do it in my code. How I would like to go about doing this is by making the code print a Number or Integer to a file to represent a Level. For example if you completed level 1 the number in the file would be 1. I have tried some templates for this but none of them work.
I understand how to write to a file but my problem is reading it from a jar or even creating a file then reading it from a place on the computer. I need to know how to find a file URL for different computers because some use Docs and Settings and other Users. Please could someone help.
Since the jar is read only, it can only contain the 'default settings'. See this answer for the general strategy to deal with such a embedded-resource.
Speaking of which (embedded resources) see the info. page for more details on how to access them.
Here is an example of storing and reading a Properties file from the 'current directory'.
As mentioned by #MadProgrammer though, it is safest to put the settings file into a (sub-directory) of user.home, as seen in this answer.
But a properties file is just one option. You might also serialize an object, or write the file in a custom format that your app. knows how to read, for the first two off the top of my head.
Besides 'serialize (in some form) in a File', there is also the Preferences API, or for desktop applications launched using Java Web Start, the PersistenceService. Here is a demo. of the service.
I need to know how to find a file url for different computers because
some use Docs and Settings and other Users
The System property user.home points to the user's home directory
File userHome = new File(System.getProperty("user.home"));

Java - Unable to find a file path which certainly exists

I am sure this is a relatively simple question, and I actually think it may be more of a problem with Windows than with Java.
I have a method for copying a file to a new directory, which takes two File objects, a File created with the path of the original, and a File created with the desired path of the copy. I am sure that the method works because I have used it to successfully copy a file onto my Desktop.
However, using my actual desired path creates an error:
java.io.FileNotFoundException: PATH (The system cannot find the path
specified)
Where the PATH is the path that I am attempting to use.
Here is my guess:
I am making this program for use on another machine. As such, the path that I am trying to use is:
C:\Users\XXXXXX\rest_of_path\filename.file
where XXXXXX is the primary user on the machine which I am writing the program for.
This directory exists on my system, but XXXXXX is not a user on my system. So I am guessing that Windows is causing a problem because of that.
I'm now changing my code to use a solution which depends on the machine, and is not hardcoded (System.getProperty).
However, I'd really like to know why this problem is occurring, from an academic standpoint, as a Windows and Java user.
Thanks in advance.
EDIT: accidentally used forward slashes when I meant double backslashes. To ensure that it was not a spelling error, I simply copied the directory using windows, and pasted it into my program (then doubled up on the backslashes).
EDIT: several users have suggested something which is far more clean than what I am trying to do in the first place. I'm leaving this question open because I'm curious why it is not working.
EDIT: I used the solution above and I'm completely happy with it. I still don't know why Windows will not allow me to access the original path, but I guess I really don't care at this point. Thanks, everybody!
In java, and generally most programming languages, you don't always have to provide the exact directory of your file. Although it would be nice to see the code you're using to get the file, I'll provide how it can be done.
I'm assuming you aren't using new File("file.txt") because that retrieves files from the folder your program is in, and doesn't require an entire address like C:\...\...\.... You certainly don't want to use an entire address because different operating systems use different paths, obviously.
The best you can do is put your files and requested folders somewhere relative to your program is (whether it's class files or a .jar file).
But with Windows you can be sure that with System.getProperty("...") you can retrieve directory URLs as relative paths for your files/folders.
Documentation on System.getProperty here: http://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html
I may not have helped or answered your question at all. But hopefully you'll find a solution.

Save something into JAR

I have a java app, that needs to save and load user settings. I want to save them in a file located in the JAR file, how could I achieve this?
That's not possible. Rather consider using java.util.prefs.Preferences which is designed for exactly this purpose. See also this little guide.
This is not a sensible course of action.
A JAR file is basically just a ZIP file. To rewrite its contents you need to extract them in full, make changes as needed and then write them to a new file that replaces the old one.
If the program that is going to do this is the same one as that contained in the JAR file, this becomes impossible as the file is write protected during execution.
You'd be better advised to store your configuration elsewhere.
That is not the way to store preferences as others said.
If you has to do it that way then :
Locate the JAR from code: How to get the path of a running JAR file?
Unjar the contents to temp folder
Modify in the temp folder
Jar temp folder to the new JAR file.
To add to what Kris said, most security experts will tell you that it's generally a bad security practice to allow end-user applications to modify their own code. What you're asking for would require that.

Categories

Resources