1

Possible Duplicate:
How can a Java program use files inside the .jar for read and write?

I am in the process of creating a game, and I want it all to run from on runnable jar file, so all of my resources (images and text files) are going to be inside the jar file.

The problem that I'm having with this is that it is extremely difficult to deal with files inside the jar.

I am using eclipse, which can sometimes play tricks on you because it will find the files if you run it from eclipse, but if you export it won't.

I just want to know basically the proper way to dew a few things:

  1. I need to be able to load images (which I have working, somehow. I sort of tinkered with it and did it on accident, so I have no clue how it works)
  2. I need to be able to read from text files (I have this working too, again, by accident and hours of guessing.)
  3. I need to be able to write to text files that exist and and are in the jar. This is what is making me think I'm doing it all wrong. All I want to do is be able to save certain settings so they work on the next load, and I have no clue how to write to the file.

In eclipse (Indigo) I made a folder names "resources" and marked it as a source folder. I put all of my images and text files in there. I read in images like this:

public static Image ammo = new ImageIcon(TankMazeGame.class.getResource("ammo.png")).getImage();

I read text files like this:

InputStream is = TankMazeRunner.class.getClassLoader().getResourceAsStream("Settings.txt");
Scanner settingsReader = new Scanner(new InputStreamReader(is));

I am writing to my settings file like this, but it isn't really working, so that's what I need help with.

File settingsFile = new File(DisplayMenu.class.getClassLoader().getResource("Settings.txt").getFile());
try {
    OutputStream os = new FileOutputStream(settingsFile, true);
    PrintWriter pw = new PrintWriter(os, true);
    pw.write("SIZE: " + TankMazeRunner.WIDTH + "\n");
    os.flush();
    pw.close(); 
} catch (Exception e2) {
    System.out.println("Error");
}

As you can probably tell from my code, I'm lost.

Community
  • 1
  • 1
Monkeybro10
  • 267
  • 1
  • 4
  • 8
  • There is a Settings.txt in the resources folder. I just need a way to write to it. Reading from it should be okay, unless I did everything wrong or there's a better way. – Monkeybro10 Jan 20 '13 at 06:10
  • Reading images and default settings from the classpath should be fine, but how about you write settings to a well known location outside of the jar (next to the jar? Specially named temp dir?). Then when you read settings you look for the well known file, lacking that you fall back to the defaults? – Charlie Jan 20 '13 at 06:20
  • 1
    See [How can a Java program use files inside the .jar for read and write?](http://stackoverflow.com/q/5052311/418556) Access the resources as an [embedded-resource](http://stackoverflow.com/tags/embedded-resource/info). – Andrew Thompson Jan 20 '13 at 07:04

2 Answers2

4

For others who come across this question.

You cannot do this unless you can place constraints on the OS being used, and even then you may not be able to do this.

Here are some constraints to be aware of:

  • Microsoft Windows implements its own read-write lock symmantics: you cannot write to a file while there is a read handle open. The JVM will have a read handle open as the this is the file on the classpath, therefore not possible in Java (unless you want to fork a temporary process, kill yourself, let the temp process rewrite and relaunch... Which will be ugly and the anti-virus will likely stop the temp process anyway)

  • Most unix OS implementations will have no issue, though the JVM will have cached offsets within the JAR file, so your program will crash as soon as you are done and attempt to load a class.

  • only windows users tend not to use file permissions to lock down write access to executables, so it is invalid to assume you have write access on the jar.

The second point has you dead in the water for all OS impls (unless you can live with a fork, and the fork makes a lot of risky assumptions anyway)

Just write to a separate file and be done.

Stephen Connolly
  • 13,872
  • 6
  • 41
  • 63
  • 1
    +1 for valuable background; more [here](http://stackoverflow.com/q/1224817/230513) and the [duplicate](http://stackoverflow.com/questions/5052311/how-can-a-java-program-use-files-inside-the-jar-for-read-and-write). – trashgod Jan 20 '13 at 11:45
1

How about you write settings to a well known location outside of the JAR?

As alternatives for saving settings, consider one of these approaches:

  • java.util.prefs.Preferences, mentioned here.

  • JWS PersistenceService, described here.

  • Cookies, discussed in Accessing Cookies.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • I really don't know why I was so hung up on saving it in the jar. I decided to just make a data folder that creates whenever you change the settings. I'll use it to store custom levels and stuff later too. They'll be easier to access that way anyway. – Monkeybro10 Jan 20 '13 at 07:14
  • I always _seems_ like a good idea; at first :-) Kudos for embracing an alternative. – trashgod Jan 20 '13 at 11:48