I'm making a game for a school assignment, one of the features is that the game can be saved and loaded. While in eclipse everything worked but after making it an executable jar it won't create the file at the specified location.
I am using this code to get it to save in the folder I want:
see below for full code
Note that the folders, quarto & savefiles, are created but the save file itself isn't.
I'm writing object to a .sav file using this code:
see below for full code
Does this have to do with permissions?
Edit: Ran it in cmd, no exceptions when i tried to save. Added a java.policy file to the folder the jar was in, no difference. I got a previously saved file and put it in the quarto/savefiles map because I wanted to see if it did load correctly (this also uses the user.home to get to the right folder). It loaded correctly. I also searched for the savename.sav to see if it saved it somewhere else, didn't find anything.
Full class:
package quarto;
import java.io.File;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
public class TaskSpelOpslaan extends SpelGegevens{
public static void runSpelOpslaan() {
String savename = SpelOpslaanScherm.getSaveName();
String userHome = System.getProperty("user.home") + File.separator + "quarto" + File.separator + "savefiles";
String locatie = userHome;
File folder = new File(locatie);
if (!folder.exists()) {
folder.mkdirs();
}
try{
if(!savename.contains(".sav"))
{
savename = (savename+".sav");
}
else
{
return;
}
FileOutputStream saveFile=new FileOutputStream(folder+File.separator + savename);
ObjectOutputStream save = new ObjectOutputStream(saveFile);
save.writeObject(bordInfo);
save.writeObject(stukGeplaatst);
save.writeObject(stukGeselecteerd);
save.writeObject(spelerBeurt);
save.writeObject(gekozenStuk);
save.writeObject(bordImage);
save.writeObject(stukImage);
save.writeObject(naamSpeler1);
save.writeObject(naamSpeler2);
save.close();
}
catch(Exception exc){
exc.printStackTrace();
}
}
}
EDIT2: I'm thankful for all your help, but I just realized a really stupid mistake i made... else{return;} didn't do what I taught it did and could be removed altogether.
Sorry for the trouble!
Is there anyway to mark this question closed or should i just let it sit?
Java programs (especially applets) tend to need permissions to do stuff like read and write files. That's why there are .policy files. Add a file called java.policy into the same dirrectory as the jar. In the file you have to grant permissions. So put this into the .policy file:
grant CodeBase "Example.jar"
{
permission java.security.AllPermission;
};
This will grant all the permissions for Example.jar.
Related
I'm writing a program that is required to save a project in a chosen directory. Every project directory must include an HTML file, which may have varying elements depending on the state of the project, along with a standard library of JavaScript files in a sub-directory.
I'm not familiar with the means by which this would usually be accomplished in Java (or even how it could be accomplished in theory). Is there a particular tool, technique or library out there that would be suited to this task? Note that I'm using Eclipse as my IDE. I've been thinking about generating the files required using templates of some kind, and/or extracting them from a package, but I'm very new to this kind of problem and am not sure how to proceed from here.
EDIT: Elaborating further
My project is a small utility for my personal use, so maintainability won't be much of an issue. I'm using Java 8. Within each user created project there will only be three unchanging .js files in the library and a small html file that will be launched in a browser to run the scripts, along with a user generated .js file. Very basic stuff.
EDIT: Problem solved... I think
I've come up with my own partial solution, and I think I can figure the rest out from here, but D.B.'s post was still informative and helpful, so I'm accepting it as the answer.
I realize that my original question wasn't specific enough. I was hoping to hide my static script resources and the template for the HTML file so that they could not be directly accessible from the file system. I had been considering placing them within some kind of package file that would reside in the same directory as the application jar. It slipped my mind, however, that I could simply place them in a resource folder within the jar itself.
Creating the libraries directory within the user specified project directory:
libraryDir = projectDir.resolve("libraries");
new File(libraryDir.toUri()).mkdirs(); // Create libraries directory
// Unpack library resources to project
unpackLibrary("file1.js");
unpackLibrary("file2.js");
unpackLibrary("file3.js");
the unpackLibrary function:
private void unpackLibrary(String scriptName) {
String resourcePath = "/libraries/" + scriptName;
Path fileName = Paths.get(resourcePath).getFileName();
try (InputStream in = getClass().getResourceAsStream(resourcePath);) {
Files.copy(in, libraryDir.resolve(fileName));
}
catch (FileAlreadyExistsException e) {
System.out.println("File unpack failed: File already exists (" + e.getFile() + ")");
}
catch (IOException e) {
e.printStackTrace();
}
}
The application will work with a project in a temporary directory until the user decides to save it, in which case I will use D.B.'s suggestions to copy the project files to the new directory.
How you proceed is entirely up to you and your project requirements. It really depends on what these files are going to be used for, how they will be maintained, etc. Using templates would seem to be a good solution since then you can simply replace variables/tokens in the template when generating a new set of project files. Whether or not those templates are somehow packaged/zipped is again up to you. If you have a good reason to package or zip them then do so, if not then there's really no reason they would need to be.
If you do use templates the basic technique would be: read the template, process the template by replacing variables/tokens with values, write the resulting data to a new file.
If you're using Java 1.7 or higher take a look at the java.nio package and the tutorial for Java file I/O featuring NIO as it's very good and will help you to understand the API and how to use it to manipulate files.
Hope this helps to get you started.
EDIT -- Here is the update I promised in my comment:
As I understand it the program must copy a set of static files into a new directory. Since you have a "project" concept going on I don't think that the code should replace existing files, so if the project files already exist this program will fail out.
Assumptions:
The static template files will reside in a folder that exists inside the current working directory for the application jar file. That is, if your executable jar lives in the folder C:\MyProgram (assuming a Windows file system) then your templates will exist in a folder within that folder - C:\MyProgram\templates for example.
The program should create the entire directory tree structure up to and including the "project" folder.
Here is the code:
SaveProjectFolderMain.java
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class SaveProjectFolderMain {
//Note: In eclipse your templates folder must be inside the eclipse project's root directory
// in order for this path to be correct. E.g. myProject/templates
// If this program is run outside of eclipse it will look for a templates folder
// in the current working directory - the directory in which the jar resides.
// E.g. if you jar lives in C:\myProgram then your templates should live in
// C:\myProgram\templates (obviously this is a Windows file system example)
private static final Path TEMPLATES_DIR = Paths.get("templates");
public static void main(String[] args) {
//Copies the template files to a new folder called "testProject"
// creating the project folder if it does not exist.
saveProjectDir(Paths.get("testProject"));
}
public static void saveProjectDir(Path dirToSaveTo){
try {
if(!Files.exists(dirToSaveTo)){
System.out.println("The directory " + dirToSaveTo.toAbsolutePath() + " does not exist, it is being created.");
Files.createDirectories(dirToSaveTo);
}
Files.walkFileTree(TEMPLATES_DIR, new CopyFileVisitor(dirToSaveTo));
} catch (IOException e) {
System.err.println("Unable to copy template files to the save location: " + dirToSaveTo.toAbsolutePath());
e.printStackTrace();
}
}
}
CopyFileVisitor.java
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
public class CopyFileVisitor extends SimpleFileVisitor<Path> {
private final Path targetPath;
private Path sourcePath = null;
public CopyFileVisitor(Path targetPath) {
this.targetPath = targetPath;
}
#Override
public FileVisitResult preVisitDirectory(final Path dir,
final BasicFileAttributes attrs) throws IOException {
if (sourcePath == null) {
sourcePath = dir;
} else {
Path destDir = targetPath.resolve(sourcePath.relativize(dir));
System.out.println("Creating directory: " + destDir);
Files.createDirectories(destDir);
}
return FileVisitResult.CONTINUE;
}
#Override
public FileVisitResult visitFile(final Path file,
final BasicFileAttributes attrs) throws IOException {
Path destFilePath = targetPath.resolve(sourcePath.relativize(file));
System.out.println("Copying " + file.toAbsolutePath() + " to " + destFilePath.toAbsolutePath());
Files.copy(file, destFilePath);
return FileVisitResult.CONTINUE;
}
}
I would like to write to a .txt file that is inside a package. I can get it to read from the exact location the .txt file is stored but not from inside the package. I'm assuming it is using class loaders but I cannot seem to get it to work.
Here is what I have so far.
public void writeFile(String fileLocation) {
Writer output = null;
File file = new File(fileLocation);
try {
output = new BufferedWriter(new FileWriter(file));
output.append("WRITING TEST");
output.close();
} catch (IOException ex) {
System.out.println("Couldn't write to file.");
}
}
Then I use this in another class to write.
WriteFile writeFile = new WriteFile();
writeFile.writeFile("src/com/game/scores.txt");
I understand that if using class loaders you remove "src/" because that will no longer exist when the program is compiled in a .jar.
It is not possible to write or update a file inside jar. Since jar itself is a file.
Please refer this link.
Write To File Method In JAR
You could use a class in that package to give you the location of the folder.
Try something like
public URL getPackageLocation() {
return getClass().getResource(".");
}
This should give you the location of the folder from which this method is being called from.
From the comments you already know that you cann't write to a file, which resides in a JAR file. At best what you can do, is creating your file, relative to the path where the JAR is located like bellow:
mylocation
|-- my-jar.jar
|-- com
|--game
|--myfile.txt
I would like to write to it to update the scores in my game as the
user goes through the levels.
While it might be possible to write to the JAR file, I don't recommend it for this use case. Just write it somewhere at:
Path userdir = Paths.get(System.getProperty("user.home"), ".myApp", "<my app version>");
You can't write into Jar file. Writing into Jar file is not recommendable. You can write outside the jar file.
Please refer this and this stack overflow question for more details.
Trying to learn how to read text files in Java. I have placed the text file within the same folder as IdealWeight.java. Am I missing something here?
IdealWeight.java
package idealweight;
import java.util.*;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class IdealWeight
{
public static void main(String[] args)
{
Scanner fileIn = null; //Initializes fileIn to empty
try
{
fileIn = new Scanner
(
new FileInputStream
("Weights.txt")
);
}
catch (FileNotFoundException e)
{
System.out.println("File not found!");
}
}
}
You could also put the file in the classpath and then do this:
InputStream in = this.getClass().getClassLoader()
.getResourceAsStream("Weights.txt");
Just another idea.
The java file IO system does not look for the file in the same directory as the class, but in the "default" directory for the application. Any application you run has a directory that it regards as its default, and that's where it would attempt to open this file. Try putting a full pathname to the file.
Or put the file you want to read in a directory, and run the application from that directory (in a terminal window) with "java IdealWeight".
You need to put Weights.txt in your working directory, not in the directory with the source file. If you're using Eclipse or a similar IDE, the this is probably the project root. As per this answer, you can use this snippet to get the full path to your working directory:
System.out.println("Working Directory = " + System.getProperty("user.dir"));
Check the result of running that command, and that should tell you where to put your text file. Once you have the text file in the right place then the code you posted should work fine.
I am trying to output numeric values one at a time from an Android application I'm writing, but I'm having a lot of trouble figuring out what's going on. Tried looking for answers, but only confused further. This strikes me as something that should be relatively straightforward, so I feel pretty dumb for being so confused by it.
String directory = Environment.getExternalStorageDirectory().getAbsolutePath();
When I log the directory I get a path "/storage/emulated/0" Where is that? Is that different from what I would get if I wasn't debugging?
Then I have:
String fileName = directory + "/Android/data/com.sample.app/files/test.txt"
File myFile = new File(fileName);
FileOutputStream fos;
try {
fos = new FileOutputStream(myFile);
String text = "Test text\n";
fos.write(text.getBytes());
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e){
e.printStackTrace();
}
I tried using the Windows Explorer to figure out where stuff is saving and/or is supposed to be saved but I don't see it. This is code based on the information in this link: http://developer.android.com/guide/topics/data/data-storage.html, but I really don't understand where the "/storage/emulated/0" comes from and how I either access that location or get rid of it.
EDIT: Right now I just want to save all the numbers so I can check what is coming out. The numbers are recorded from the audio input.
EDIT: Using the ASTRO File app on my phone revealed the files
Didn't need the "/Android/data/com.sample.app/files/" part, don't know how to use that.
Path wrong?
/storage/emulated/0 is a path at your filesystem which represents the external storage. At earlier versions of Android we often had /mnt/sdcard/ or something similiar, but many devices today don't have a sdcard but emulate an external storage anyway.
To view the files at your Android filesystem I'd recommend to use an App like Astro File Manager. Just take a look if your file has been written.
One possible mistake could be, that you you are missing a File.separator between your directory and the local path.
String fileName = directory + File.seperator + "Android/data/com.sample.app/file/test.txt"
Directory created?
You should also make sure, that the directory exists by calling myDir.mkDirs();, where myDir is the complete path without the filename.
To create the directory you can use the following code
directory = directory + "/Android/data/com.sample.app/file/test.txt"
new File(directory).mkDirs();
Uses-Permission in Manifest?
Last error source could be, that you might miss the external storage permission, you need a
You also need to make sure, that you require the permission for writing to the external storage. Take a look for <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> in your Android Manifest file.
Lets say I'm making a program that needs to copy all the lines in a .txt file within my .jar file. it is in the package program.files and it is named text.txt. I've been looking all over the internet, and i cant find what I'm looking for. i think that this idea:
public String readSpecificFromJar(String dir, int line) {
String read = null;
try {
InputStream in = getClass().getResourceAsStream(dir);
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(in));
/**
* declare string variable and prime the read
*/
read = bufferedReader.readLine();
for (int i = 1; i < line; i++) {
read = bufferedReader.readLine();
}
bufferedReader.close();
} catch (IOException ioexception) {
Dialogs.fail("Could not read txt file from the JAR!!! Error Code: 06");
}
return read;
}
would work, but i tried that and it gave me all kinds of errors. what i think the problem would be is declaring the InputStream in the way it does it want the file to be right there with the Main method. how would i change this so it is not the case? thanks in advance!
EDIT:
due to some confusion, i want to clear this up. for the String dir i am entering files/text.txt. it wont work. how do i fix this?
EDIT 2:
OK i feel like the problem isn't getting across, and I'm kinda getting aggravated, mainly because I'm pretty tired. the code that WORKS for a different program is up above, where the dir is simply "text.txt"
THIS DOESN'T WORK FOR WHAT I'M DOING AND IM NOT SURE WHY. again, the file is IN THE CLASSPATH so dir is only "text.txt". I want my .txt file to be "files/text.txt". How do i do this?
EDIT 3:
I dont know if i mentioned it, but my .txt file is INSIDE my jar. just to clear up the confusion. so really, the path of the .jar file shouldn't matter, as in I shouldn't have to type it in with the dir. also, the main class is in the package main and the .txt file is in the package files all within the same program named copy. also, i tried moving the txt file to the same package as the main class, also didn't work.
EDIT 4:
by the way, the package that holds the method for reading from the jar is IO. as in the class io is inside the package IO. all of my files such as images and txt are in the package files. just thought id clear that up. i tried moving the txt file to the package of the io class, and that worked, but if its in any other package, even if i include the package name in the dir it wont work. any ideas as to why?
The .txt file should be in The root directory of dir is the same directory where your class file is located in.
EDIT: due to some confusion, i want to clear this up. for the String
dir i am entering files/text.txt. it wont work. how do i fix this?
What is the path of the class? (the class that contains readSpecificFromJar()) If the .class file and the .txt file are both in the same directory, then you should make it like this:
dir = "text.txt";
EDIT 4: by the way, the package that holds the method for reading from
the jar is IO. as in the class io is inside the package IO. all of my
files such as images and txt are in the package files. just thought id
clear that up. i tried moving the txt file to the package of the io
class, and that worked, but if its in any other package, even if i
include the package name in the dir it wont work. any ideas as to why?
Try this:
dir = "../files/text.txt";
I believe this would work if your structure is as follows:
javaApp.jar
|
_____|_____
| |
files IO
| |
| |
text.txt io.class