Search code examples
javajarnio

FileSystem error when trying to close it


Currently I'm trying to make a level editor for a Java game that I created.
My problem is that my program doesn't save the edited levels.

Here is the code that I made so far:

Path path = Paths.get(gameFile.getAbsolutePath());
FileSystem fs = FileSystems.newFileSystem(path, null);
Path p = fs.getPath("rpg"+fs.getSeparator()+"levels"+fs.getSeparator()+"level"+(short)level+".png");
OutputStream os = Files.newOutputStream(p);
ImageIO.write(img, "png", os);
os.close();
fs.close();

gameFile is the .jar file of my game which contains the levels and the levels are saved as .png files.
I have tried to save my picture outside of the jar and it worked so i guess i made a mistake with the FileSystem or the Path.
The Path in the jar is rpg/levels/level*.png

Edit:
I changed

OutputStream os = Files.newOutputStream(p);

to

OutputStream os = Files.newOutputStream(p,StandardOpenOption.CREATE,StandardOpenOption.TRUNCATE_EXISTING);

but now I get an error when closing the fileSystem

java.nio.file.FileSystemException: G:\RPG.jar: The process cannot access the file because it is being used by another process.

at sun.nio.fs.WindowsException.translateToIOException(Unknown Source)
at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source)
at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source)
at sun.nio.fs.WindowsFileSystemProvider.implDelete(Unknown Source)
at sun.nio.fs.AbstractFileSystemProvider.delete(Unknown Source)
at java.nio.file.Files.delete(Unknown Source)
at com.sun.nio.zipfs.ZipFileSystem.sync(ZipFileSystem.java:1294)
at com.sun.nio.zipfs.ZipFileSystem.close(ZipFileSystem.java:277)
at de.jorolf.editor.LevelEditor$5.actionPerformed(LevelEditor.java:213)

Solution

  • You can not save anything inside of a running jar-File (related: updating-a-jar-whilst-running).

    Also, if you want to save something inside of a not running jar-File, then you also need to save the file compressed. For this task you can simply add a ZipOutputStream to your stream-queue (Java-Doc: ZipOutputStream.html). Also java.util.jar.JarFile and java.util.jar.JarEntry may be helpful.

    For your general task, you should save the level file outside of the jar. You may distribute the game in a folder game with /game/theGame.jar and /game/firstLevel.lvl. Then the level is outside of the jar and you can modify it.

    Also you may use common directories as other games do, like Windows Documents or AppData for game specific settings and data.

    MyDocuments in Java: FileSystemView.getFileSystemView().getDefaultDirectory().getPath() AppData in Java: System.getenv("APPDATA")