How can I plus file's info? - java

I'm making a new game and I wanna make a coins collector to, later, buy things with those coins. I'm using eclipse.
void save() {
try {
PrintWriter out = new PrintWriter("coins.txt");
out.write(Integer.toString(nmonedas));
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
void load() {
StringBuffer texto=new StringBuffer();
try {
int c;
#SuppressWarnings("resource")
FileReader entrada=new FileReader("coins.txt");
while((c=entrada.read())!=-1){
texto.append((char)c);
}
}
catch (IOException ex) {}
labelshow.setText(texto.toString());
}
I have this code but i cant plus the info. NEED HELP PLS
Well, the thing is, I'm doing a game in eclipse and I want you to collect coins and keep them in a file.
They are collected perfectly and stored in the file, but when I start the game again I want them to be collected but they add up with the previous ones

I assume you are referring to appending text to a .TXT file. If so, you can use something like this:
Files.write(Paths.get("Path to text file here"), "Content".getBytes(), StandardOpenOption.APPEND);
I would put the above in a TRY CATCH block. Also look into PrintWriter as this may be more appopriate to what you need it for as it allows you to continuously write to the file.

Related

Loading data from an RPG game

So I'm working on a simple RPG game. I want to add an option to load progress through the game, but I guess I'm not that familiar with Java to do it without issues. The idea is to save the game on checkpoints, and load a saved data when the game continues. I'm getting an error with a loadGame method, and I guess it's related to the fact that the data I'm trying to load are all different data types. health and level are integers, while equippedItem is a string.
Here are just two methods, saveGame, and loadGame, because the code is a bit too long to simply paste it in the whole. I'll put additional code if needed of course.
public static void saveGame() {
try {
BufferedWriter bw = new BufferedWriter(new FileWriter("savedGame.txt"));
bw.write("Your health is " + player.getHealth());
bw.newLine();
bw.write("Your level is " + player.getLevel());
bw.newLine();
bw.write("" + player.equippedItem);
bw.close();
}
catch (Exception e) {
System.out.println("There's an error.");
}
}
The saveGame() doing its work well, it stores the data in the file. The issue is with the loadGame() method.
public void loadGame() {
try {
BufferedReader br = new BufferedReader(new FileReader("savedGame.txt"));
player.getHealth();
player.getLevel();
player.equippedItem;
br.close();
} catch (Exception e) {
System.out.println("There's an error.");
}
}
The result of player.getHealth() and player.getLevel() is ignored, and it's probably the data type issue I've mentioned.
What you're doing is creating a text file in saveGame(), 'opening' that save file in loadGame() but not accessing the data inside.
You have correctly created a BufferedReader, but you're using it incorrectly. You will need to use br.readLine() to read the text file which will return a string like "Your health is 123".
To update the state of the player with this data, you could add something like this inside loadGame():
player.setHp(parseHp(br.readLine()));
player.setLevel(parseLevel(br.readLine()));
... // and so on
The parse methods would take a String input like "Your health is 123" and return int 123.

Program design when using BufferedWriter, do I repeatedly open and close file?

I have a program that does a lot of processing with loops and writes strings to a file at many different points. I'm not sure about the overall design for how best to do this. I won't need to read from the file at any point during running, though will want to view it afterwards.
Firstly, is a BufferedWriter with FileWriter a reasonable way of doing this?
Secondly, presumably I don't want to be opening and closing this every time I want to write something (several times per second).
But if I use try with resources then I'd have to put practically the entire program inside that try, is this normal?
At the moment the skeleton looks like:
try (FileWriter writer = new FileWriter("filename.txt");
BufferedWriter bw = new BufferedWriter(writer)) {
} catch (IOException e) {
//catch IO error
}
for (//main loop){
bw.write(string);
for (//several sub loops){
bw.write(//more strings);
}
for (//several sub loops){
bw.write(//more strings);
}
}
bw.write(//final string);
try {
bw.close();
} catch (IOException ex) {
//catch IO error
}
Does this look reasonable or is there a better way? Thanks very much in advance for the help.
Edit - thanks to you all for the help, totally answered my questions.
Firstly, is a BufferedWriter with FileWriter a reasonable way of doing this?
Yes, it should be the most convenient way to do this.
Secondly, presumably I don't want to be opening and closing this every time I want to write something (several times per second).
You really shouldn't. But you would actually overwrite your progress this way everytime you open the file anyway. That's because you didn't tell the FileWriter to append to an existing file (via new FileWriter("filename.txt", true);.
But if I use try with resources then I'd have to put practically the entire program inside that try, is this normal?
I don't see a problem with that. You can (and should) always move your logic into own methods or classes, which may return the Strings to write. This way you get the actual business logic separated from the technical file writing logic and structure your code, making it easier to understand.
You could also just write into a giant big String and then write that String in the try-with-resources block. But that has it's limits with really big files and may not be the best choice sometimes.
It is totally OK to put the whole Code into a try-catch routine. Whenever you have issues to write into the file it will just catch it and does not give you an error. However, I would recommend you to try this structure with just one try-catch routine.
try { (FileWriter writer = new FileWriter("filename.txt");
BufferedWriter bw = new BufferedWriter(writer))
for (/*main loop*/){
bw.write(string);
for (/*several sub loops*/){
bw.write(/*more strings*/);
}
for (/*several sub loops*/){
bw.write(/*more strings*/);
}
}
bw.write(/*final string*/);
bw.close();
} catch (IOException e) {
System.out.println("error");
}
PS: If you comment something between some code use this:/* comment */ instead of this:// because it will comment out the whole line.
But if I use try with resources then I'd have to put practically the
entire program inside that try, is this normal?
Thats just how try-catch-with-resources work - it closes resources on exiting try block. If that is bothering you, don't use that construct and you manage writer yourself.
Above skeleton will not work as first try will open and close your writers;
Here is an alternate that does finer exception handling. In many cases, this is preferred. Having a catch block handle too many exceptions gets to be very confusing: Control flow is obscured, and diagnosing errors can be a lot harder.
Having a file open through the entire time a program is running is very usual. This is often the case for log files. If you know your program will be running for a long time, and if you suspect there will be long delays between output to a single file, you could open and close the file for each batch of close in time operations. But you would have to have a clear idea of the pattern of activity to do this, as you will want to match the open time of the file with expected close-in-time batches of writes. You should very much avoid high frequency open and close operations. That has all sorts of unwanted extra overhead.
package my.tests;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.function.Consumer;
public class WriterTest {
public static final String TARGET_NAME = "filename.txt";
public void performMainLoop() {
performWrites( this::mainLoop, TARGET_NAME );
}
public void performWrites( Consumer<Writer> writeActor, String targetName ) {
FileWriter fileWriter;
try {
fileWriter = new FileWriter(targetName);
} catch ( IOException e ) {
System.out.println("Open failure: " + e.getMessage());
e.printStackTrace();
return;
}
BufferedWriter bufferedWriter = null;
try {
bufferedWriter = new BufferedWriter(fileWriter);
writeActor.accept(bufferedWriter);
} finally {
if ( bufferedWriter != null ) {
try {
bufferedWriter.close();
} catch ( IOException e ) {
System.out.println("Unexpected close failure: " + e.getMessage());
e.printStackTrace();
}
} else {
try {
fileWriter.close();
} catch ( IOException e ) {
System.out.println("Unexpected close failure: " + e.getMessage());
e.printStackTrace();
}
}
}
}
public void mainLoop(Writer writer) {
for ( int loopNo = 0; loopNo < 10; loopNo++ ) {
try {
writer.write("Loop [ " + Integer.toString(loopNo) + " ]\n");
} catch ( IOException e ) {
System.out.println("Unexpected write failure: " + e.getMessage());
e.printStackTrace();
return;
}
}
}
}

Why is the method File.delete() not working?

I have been frustrated for almost 2 days trying to find the flaw because the registry.delete() method does not delete the file "Registry.txt". I'm working with a GUI, and every time I click on a row of a JTable and then click on the "Ban" button, it does not delete the file "Registry.txt", and it does not write either! However, if I do it from another class, like the class that has the main() method, it clears properly. What I wanted to do is delete a line from the Registry.txt, writing in another .txt file all of the lines that did not contain a certain String name, and then rename it to the name Registry.txt. I do not know what is happening. Below is my code:
ActionListener ban = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int fila = table.getSelectedRow();
String nombre = (String) modelo.getValueAt(fila, 0);
modelo.removeRow(fila);
try {
removeUser(nombre);
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
};
btnBanear.addActionListener(ban);
...
public void removeUser(String nombre) throws IOException {
String lee = null;
String usuario = "";
CharSequence aux = nombre;
try {
registro = new File("Registro.txt");
tempFile = new File("Registro1.txt");
lector = new BufferedReader(new FileReader(registro));
fw = new FileWriter(tempFile);
writer = new BufferedWriter(fw);
} catch (FileNotFoundException ex) {
System.out.println(ex.getMessage());
} catch (IOException ex) {
System.out.println(ex.getMessage());
} catch (NullPointerException e) {
System.out.println(e.getMessage());
}
while ((lee = lector.readLine()) != null) {
System.out.println(aux);
if (lee.contains(nombre)) {
continue;
} else {
writer.write(lee);
}
}
lector.close();
fw.close();
writer.close();
registro.delete();
}
I don't think we have quite enough data to see exactly why this is happening, but I can give you some strong suspicions.
File.delete() throws four possible exceptions; three of which apply here. NoSuchFileException (worth specifically checking for), IOException, and SecurityException. NoSuchFileException is derived from IOException and would be caught anyway; though you might want to catch for it still as casting it to an IOException is going to remove relevant data. SecurityException is generally when a security manager gets in the way, which happens all the time on web-based programs. I'm wondering if your file is some kind of an applet or its modern equivalent, the web application? SecurityException is a RuntimeException, so you don't have to catch for it, but you can and probably should. That would explain worlds.
Lastly, you can also use File.deleteIfExists(). This returns a value of true if the file was actually present to be deleted, and false if it could not be found. Worth looking into, because if your path is getting skewed and the file can't be found at the provided location, then it won't be deleted. It's reasonable to think that your program might have a different working directory than you're thinking it does. This is more or less the same as checking for NoSuchFileException, though.
You might even check your working directory, to be sure, with System.out.println(System.getProperty("user.dir")).
My money is on SecurityException or the path being wrong. However, if I'm wrong about this, it would be nice if you could show us your other button code, because there could be a relevant problem there, too.

ObjectOutputStream writing array to file with inherited classes not writing to file

My assignment is to save a list of employees as a binary file (and later read from it). I'm working on the output portion now, below is the block of the function that is in question. This function does have about 10 more lines but they edit things on the TextField arraylist.
The Employee class is the parent of both the Supervisor and Secretary classes. all is the ArrayList that holds all the employee, secretary, and employee objects.
I'm using netbeans 8.0.2, when the program runs and I click the save button in the gui (onActionEvent() is this function) there are no compiler errors. The "IO Error" or "No Permissions..." doesn't output. Ive tried saving both with and without the employees.dat file being already created.
I'm not really sure what to do at this point, I contemplated saving each object as a the collection of int, String, etc but that's dumb, it should be able to work this way... right?
EDIT:
Employee, Supervisor, and Secretary are all Serializable.
private void saveChanges(ArrayList<Employee> all, ArrayList<TextField> text, int index) {
try ( ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("employees.dat", true)); ) {
for (int i = 0; i < all.size(); i++) {
if (all.get(i).getClass() == (new Secretary().getClass()))
output.writeObject(new Secretary((Secretary) all.get(i)));
else if (all.get(i).getClass() == (new Supervisor().getClass()))
output.writeObject(new Supervisor((Supervisor) all.get(i)));
else
output.writeObject(new Employee(all.get(i)));
}
output.flush();
} catch (IOException io) {
io.printStackTrace();
} catch (SecurityException se) {
se.printStackTrace();
}
}
EDIT:
I have edited the try-catch to this code...
try ( ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("employees.dat", true)); ) {
output.writeObject(all);
output.flush();
output.close();
} catch (IOException io) {
io.printStackTrace();
} catch (SecurityException se) {
se.printStackTrace();
}
Still not writing to file. I have permissions in the folder the .java files are in.
try ( ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("employees.dat", true)); ) {
Change true to false, or remove it. You can't append to files created as object output streams, at least not like this, and it's debatable whether you're even supposed to be doing so.
for (int i = 0; i < all.size(); i++) {
if (all.get(i).getClass() == (new Secretary().getClass()))
output.writeObject(new Secretary((Secretary) all.get(i)));
else if (all.get(i).getClass() == (new Supervisor().getClass()))
output.writeObject(new Supervisor((Supervisor) all.get(i)));
else
output.writeObject(new Employee(all.get(i)));
}
Change this entire mess to this:
output.writeObject(all);
If this still doesn't work there must have been an exception somewhere, and you're just going to have to find it, print it, and post it. Edit it into your question. Or else you're looking at the wrong file.
NB you will also have to change the code that reads the file, to just read the list in a single readObject() call.
By any chance are you happening to write an applet or JNLP without appropriate permissions?
do you have write access to the folder that you are outputting the file ? (which in this case is the directory that the program is running in. )
I would recomend calling io.printStackTrace() and se.printStackTrace(); in the exception handlers to provide significantly more information about the exceptions.
At the end of the file writing also dont forget to call output.close() to ensure that the stream is closed properly, the tail of the data is written and there are no left over open file handles on your system.

Check if file exists from string

This is the code I use when I try to read some specific text in a *.txt file:
public void readFromFile(String filename, JTable table) {
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(new FileReader(filename));
String a,b,c,d;
for(int i=0; i<3; i++)
{
a = bufferedReader.readLine();
b = bufferedReader.readLine();
c = bufferedReader.readLine();
d = bufferedReader.readLine();
table.setValueAt(a, i, 0);
table.setValueAt(b, i, 1);
table.setValueAt(c, i, 2);
table.setValueAt(d, i, 3);
}
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
//Close the reader
try {
if (bufferedReader != null) {
bufferedReader.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
And it is called in this way:
readFromFile("C:/data/datafile.txt", table1)
The problem is the following: the 1st time I open the program the *.txt file I'm going to read does not exist, so I thought I could use the function exists(). I have no idea about what to do, but I tried this:
if(("C:/data/datafile.txt").exists()) {
readFromFile("C:/data/datafile.txt", table1)
}
It is not working because NetBeans gives me a lot of errors. How could I fix this?
String has no method named exists() (and even if it did it would not do what you require), which will be the cause of the errors reported by the IDE.
Create an instance of File and invoke exists() on the File instance:
if (new File("C:/data/datafile.txt").exists())
{
}
Note: This answer use classes that aren't available on a version less than Java 7.
The method exists() for the object String doesn't exist. See the String documentation for more information. If you want to check if a file exist base on a path you should use Path with Files to verify the existence of the file.
Path file = Paths.get("C:/data/datafile.txt");
if(Files.exists(file)){
//your code here
}
Some tutorial about the Path class : Oracle tutorial
And a blog post about How to manipulate files in Java 7
Suggestion for your code:
I'll point to you the tutorial about try-with-resources as it could be useful to you. I also want to bring your attention on Files#readAllLines as it could help you reduce the code for the reading operation. Based on this method you could use a for-each loop to add all the lines of the file on your JTable.
you can use this code to check if the file exist
Using java.io.File
File f = new File(filePathString);
if(f.exists()) { /* do something */ }
You need to give it an actual File object. You're on the right track, but NetBeans (and java, for that matter) has no idea what '("C:/data/datafile.txt")' is.
What you probably wanted to do there was create a java.io.File object using that string as the argument, like so:
File file = new File ("C:/data/datafile.txt");
if (file.exists()) {
readFromFile("C:/data/datafile.txt", table1);
}
Also, you were missing a semicolon at the end of the readFromFile call. Im not sure if that is just a typo, but you'll want to check on that as well.
If you know you're only ever using this File object just to check existence, you could also do:
if (new File("C:/data/datafile.txt").exists()) {
readFromFile("C:/data/datafile.txt", table1);
}
If you want to ensure that you can read from the file, it might even be appropriate to use:
if(new File("C:/data/datafile.txt").canRead()){
...
}
as a condition, in order to verify that the file exists and you have sufficient permissions to read from the file.
Link to canRead() javadoc

Categories

Resources