Jump to content

Java - Editing a text file

How do I do this? I would like to retrieve a number from a text file, increment it by one replace the one in the file with the incremented one and save it. 

The text file has just 1 number at the first line of the document. 

package modifying;import java.io.File;import java.io.PrintWriter;import java.util.Scanner;public class Modify {	public static void incrementByOne(){				try {						File input = new File("/modifying/assets/timesPlayed.txt");			File temp = new File("/modifying/assets/temp.txt");			Scanner sc = new Scanner(input);			PrintWriter pw = new PrintWriter(temp);						int i = sc.nextInt();			i += 1;			pw.write(i);						sc.close();			pw.close();						input.delete();			temp.renameTo(input);					}		catch (Exception e) {			e.printStackTrace();		}			}		public static void main(String[] args){				incrementByOne();			}	}

When I try to execute this code it just gives me the FileNotFoundException.

Learning

Link to comment
Share on other sites

Link to post
Share on other sites

Well my guess is that the FileNotFoundExcpetion is happening at the temp.txt file.  I am assuming that it doesn't exist. (If the timesPlayed doesn't exist either then that could also be the problem).

 

Anyways before using the temp file just create a new one

if(temp.exists())    temp.delete(); //Delete to make sure it is clear for the new filetemp.createNewFile(); //Create a file because there won't be a file after deleting

...this is just a guess though (you do this prior to putting it into printwriter....anyways that is just my guess though....also make sure the timesPlayed.txt exists as well...just in case it doesn't (say when you first created your game, I assume it is a game you are making :P)

0b10111010 10101101 11110000 00001101

Link to comment
Share on other sites

Link to post
Share on other sites

Well my guess is that the FileNotFoundExcpetion is happening at the temp.txt file.  I am assuming that it doesn't exist. (If the timesPlayed doesn't exist either then that could also be the problem).

 

Anyways before using the temp file just create a new one

if(temp.exists())    temp.delete(); //Delete to make sure it is clear for the new filetemp.createNewFile(); //Create a file because there won't be a file after deleting

...this is just a guess though (you do this prior to putting it into printwriter....anyways that is just my guess though....also make sure the timesPlayed.txt exists as well...just in case it doesn't (say when you first created your game, I assume it is a game you are making :P)

 

Mh, I have put it between the file paths and the printwriter : 

                        File input = new File("/modifying/assets/timesPlayed.txt");			File temp = new File("/modifying/assets/temp.txt");						if(temp.exists())				temp.delete();			temp.createNewFile();						Scanner sc = new Scanner(input);			PrintWriter pw = new PrintWriter(temp);

But now I get this error: 

java.io.IOException: Het systeem kan het opgegeven pad niet vinden	at java.io.WinNTFileSystem.createFileExclusively(Native Method)	at java.io.File.createNewFile(Unknown Source)	at modifying.Modify.incrementByOne(Modify.java:18)	at modifying.Modify.main(Modify.java:42)

"Het systeem kan het opgegeven pad niet vinden" is Dutch for "The system can not find the specified path" 

Learning

Link to comment
Share on other sites

Link to post
Share on other sites

Perhaps someone else could help out, I really am out of my bounds when working with file io in java...I use different methods and such usually, so I am not as familiar with it.

 

Anyways with that said I can make a guess again.  My guess would be that the directory itself might not exists...Java handles directorys like files so errors about file's not existing can also include the fact the directory itself doesn't exists (and the createfile doesn't create directories).  I would just check to make sure that /modifying/assets/ exists....also perhaps check that the file path location is in the correct area (like printing out the temp.getAbsolutePath() string to figure out it is running in the correct spot....I once had a program that liked to think it was running on the desktop...only figured it out by seeing that relative files were pointing there :P)

0b10111010 10101101 11110000 00001101

Link to comment
Share on other sites

Link to post
Share on other sites

Perhaps someone else could help out, I really am out of my bounds when working with file io in java...I use different methods and such usually, so I am not as familiar with it.

 

Anyways with that said I can make a guess again.  My guess would be that the directory itself might not exists...Java handles directorys like files so errors about file's not existing can also include the fact the directory itself doesn't exists (and the createfile doesn't create directories).  I would just check to make sure that /modifying/assets/ exists....also perhaps check that the file path location is in the correct area (like printing out the temp.getAbsolutePath() string to figure out it is running in the correct spot....I once had a program that liked to think it was running on the desktop...only figured it out by seeing that relative files were pointing there :P)

 

Okay, let me ask my question differently. How should I refer to files in Java? For example, if I have a text file in the same package as my java file, how would I refer to the text file from the java file?

Learning

Link to comment
Share on other sites

Link to post
Share on other sites

Okay, let me ask my question differently. How should I refer to files in Java? For example, if I have a text file in the same package as my java file, how would I refer to the text file from the java file?

Unfortunately I can't be too much help here.  For my java projects where I needed file IO, it was on Android...so all I used was

_context.openFileOutput("lastName.txt", Context.MODE_PRIVATE);

which I doubt will be much help.  (using the classes DataOutputStream, and FileOutputStream)...this is alright since it uses Java, but getting the Input/Output streams I use the android stuff...which is why my knowledge is sorely lacking sorry.

 

Actually I would try this first (it might be a bit better, and avoids creating the file if needed)

package modifying;import java.io.File;import java.io.PrintWriter;import java.util.Scanner;public class Modify {	public static void incrementByOne(){		//Ensures the correct directory structure exists...I think		File dir = new File("/modifying/assets");		if (!dir.exists()) dir.mkdir();		try {			int i = 0; //Default value			File input = new File("/modifying/assets/timesPlayed.txt");                        PrintWriter pw = new PrintWriter("/modifying/assets/temp.txt", "UTF-8");			//If this still doesn't work get rid of the /moditying/assets/ and just put "temp.txt"...it will simplfy the problems 			//If you haven't played before then i will be defaulted to "1" after all this is said and done			if(input.exists()) {				Scanner sc = new Scanner(input);				i = sc.nextInt();			}			i += 1;			pw.write(i);						sc.close();			pw.close();						if(input.exists()) //Deleting only when possible				input.delete();			File ouput = new File("/modifying/assets/temp.txt");			ouput.renameTo(input);					}		catch (Exception e) {			e.printStackTrace();		}			}		public static void main(String[] args){				incrementByOne();			}	}

Sorry if this still doesn't work...If it doesn't then someone else will need to help (also sorry for any syntax errors, I just wrote that in notepad...so there might be an error here and there in the syntax)

0b10111010 10101101 11110000 00001101

Link to comment
Share on other sites

Link to post
Share on other sites

 

Sorry if this still doesn't work...If it doesn't then someone else will need to help (also sorry for any syntax errors, I just wrote that in notepad...so there might be an error here and there in the syntax)

 

It still does not work. But I think the problem is that when I create a File it starts looking for the filepath from the beginning. So from the C:/ drive, most of the time.

File input = new File("/modifying/assets/timesPlayed.txt");

That is not what we want. 

Let's say I put it in a .jar, I would like it to make the text file timesPlayed.txt outside of the jar so I can access it. I have no idea how this should be done though. 

Learning

Link to comment
Share on other sites

Link to post
Share on other sites

Oh, it is inside a jar file...I am not sure you can modify resources in a jar file

 

*edit: To elaborate, usually resource files are embedded and cannot be changed.  That is why it is good to write code that will spawn the necessary directories in the final location where the jar is to be contained.

0b10111010 10101101 11110000 00001101

Link to comment
Share on other sites

Link to post
Share on other sites

Oh, it is inside a jar file...I am not sure you can modify resources in a jar file

 

*edit: To elaborate, usually resource files are embedded and cannot be changed.  That is why it is good to write code that will spawn the necessary directories in the final location where the jar is to be contained.

 

But how do I write code that will spawn the necessary directories in the final location where the jar is to be contained?

Learning

Link to comment
Share on other sites

Link to post
Share on other sites

File dir = new File("./one/two/three"); //Creates 3 folders, one two and threeif (!dir.exists()) dir.mkdir();

If I am not mistaken, this should spawn all the correct directories.  If this is placed in, let say, the main function at the very beginning I believe it will just create the directories in place (or at least it should, I am assuming that java works the same as C# in windows and java on android though) Maximation

0b10111010 10101101 11110000 00001101

Link to comment
Share on other sites

Link to post
Share on other sites

File dir = new File("./one/two/three"); //Creates 3 folders, one two and threeif (!dir.exists()) dir.mkdir();

If I am not mistaken, this should spawn all the correct directories.  If this is placed in, let say, the main function at the very beginning I believe it will just create the directories in place (or at least it should, I am assuming that java works the same as C# in windows and java on android though) Maximation

 

 

Good. So after figuring some stuff out I came up with this solution:

package modifying;import java.io.File;import java.io.FileNotFoundException;import java.io.IOException;import java.io.PrintWriter;import java.util.Scanner;public class Modify {	private static String installPath;	private static String dirPath;	private static String timesPlayedPath;	private static File timesPlayed;		public static void setDirPath(){		Scanner sc = new Scanner(System.in);		System.out.print("Where would you like to store the directory? \n:\t");		installPath = sc.nextLine();		sc.close();			}		public static void createDirs(){			dirPath = installPath + "/Modify";		File dir = new File(dirPath);		if (!dir.exists()){			dir.mkdir();			System.out.println("Succesfully created dir in " + dirPath);		}		else {			System.out.println("Dir already exists");		}	}		public static void createStatsFile(){				timesPlayedPath = dirPath + "/timesPlayed.txt";		timesPlayed = new File(timesPlayedPath);		try {			if(!timesPlayed.exists()){				PrintWriter pw = new PrintWriter(timesPlayed);				timesPlayed.createNewFile();				pw.print(0);				pw.close();				System.out.println("Created the file timesPlayed.txt");			}			else {				System.out.println("The file timesPlayed.txt already exists");			}		} 		catch (IOException e) {			e.printStackTrace();		}			}		public static void incrementByOne(){				try {			Scanner sc = new Scanner(timesPlayed);			int i = sc.nextInt();			i += 1;			PrintWriter pw = new PrintWriter(timesPlayed);			pw.print(i);			sc.close();			pw.close();		} 		catch (FileNotFoundException e) {			e.printStackTrace();		}	}		public static void main(String[] args){				setDirPath();		createDirs();		createStatsFile();		incrementByOne();			}	}

It asks the user where to generate the directory and the files. There are some problems though.

At the moment it asks every time the application gets started where to generate the dir and its files, how can I let it remember where to store all the files?

 

After I got this working I implemented it in my simple game. But when I try to execute it it gives me an error at a scanner in another class. When I do not include this class it works fine. Would you like to see the code behind this? It is quite a lot though..

Learning

Link to comment
Share on other sites

Link to post
Share on other sites

After hours of debugging I finally came up with a working solution. Here is the implementation in my simple hangman game.

Thank you @WanderingFool for helping me out and pushing me in the right direction. :)

package hangman;import java.io.File;import java.io.FileWriter;import java.io.IOException;import java.io.PrintWriter;import java.util.Scanner;public class Files {	private static int i = 0;	private static File dir = new File("Hangman");	private static File timesPlayed = new File("Hangman/timesPlayed.txt");	private static File timesWon = new File("Hangman/timesWon.txt");	private static File timesLost = new File("Hangman/timesLost.txt");		public void generateFiles(){				createFiles();		incrementTimesPlayed();			}		private static void createFiles(){				try {						if (!dir.exists())				dir.mkdir();						if (!timesPlayed.exists()){				FileWriter fw = new FileWriter(timesPlayed);				PrintWriter pw = new PrintWriter(fw);							pw.println(i);							pw.close();			}						if (!timesWon.exists()){				FileWriter fw = new FileWriter(timesWon);				PrintWriter pw = new PrintWriter(fw);								pw.println(i);								pw.close();			}						if (!timesLost.exists()){				FileWriter fw = new FileWriter(timesLost);				PrintWriter pw = new PrintWriter(fw);								pw.println(i);								pw.close();			}					}		catch (IOException e){			System.out.println("Error..");		}				}		private static void incrementTimesPlayed(){				try {						Scanner scan = new Scanner(timesPlayed);						i = scan.nextInt();			i += 1;						scan.close();					}		catch (IOException e){			System.out.println("File not found..");		}				try {						FileWriter fw = new FileWriter(timesPlayed);			PrintWriter pw = new PrintWriter(fw);						pw.print(i);						pw.close();					}		catch (IOException e){			System.out.println("Error..");		}			}		/*	 * Handles the end result of the game. 	 * Guessing.java should give the boolean value depending on the ending of the game	 * If the player has guessed the word the argument will be true, 	 * however, if the player was not able to guess the word the argument will be false	 */	public void resultHandler(boolean result){				if (result)			incrementTimesWon();		else if (!result)			incrementTimesLost();			}		private static void incrementTimesWon(){				try {						Scanner scan = new Scanner(timesWon);						i = scan.nextInt();			i += 1;						scan.close();					}		catch (IOException e){			System.out.println("File not found..");		}				try {						FileWriter fw = new FileWriter(timesWon);			PrintWriter pw = new PrintWriter(fw);						pw.print(i);						pw.close();					}		catch (IOException e){			System.out.println("Error..");		}			}		private static void incrementTimesLost(){				try {						Scanner scan = new Scanner(timesLost);						i = scan.nextInt();			i += 1;						scan.close();					}		catch (IOException e){			System.out.println("File not found..");		}				try {						FileWriter fw = new FileWriter(timesLost);			PrintWriter pw = new PrintWriter(fw);						pw.print(i);						pw.close();					}		catch (IOException e){			System.out.println("Error..");		}			}	}

Learning

Link to comment
Share on other sites

Link to post
Share on other sites

this hurts my eyes: 

i += 1;

:P

i++;

Best regards Zahlio,
Unity asset developer - Game developer (http://playsurvive.com) - Computer Science student

Link to comment
Share on other sites

Link to post
Share on other sites

Also would it not be better to save the stuff in a XML (using jDOM) or .properties file?

Best regards Zahlio,
Unity asset developer - Game developer (http://playsurvive.com) - Computer Science student

Link to comment
Share on other sites

Link to post
Share on other sites

 

this hurts my eyes: 

i += 1;

:P

i++;

 

Haha I am sorry. :D

Mh weird, I have always done it like this except when I am implementing a for loop. Interesting.

Learning

Link to comment
Share on other sites

Link to post
Share on other sites

Also would it not be better to save the stuff in a XML (using jDOM) or .properties file?

 

How should I do that?

Learning

Link to comment
Share on other sites

Link to post
Share on other sites

Also would it not be better to save the stuff in a XML (using jDOM) or .properties file?

To be honest, I think too many people put reliance on XML files in Java (I had a teacher who kept pushing for this as well).  The reason why I think XML is overused is that people use it when information isn't going to be passed to other applications.  XML does have it's purposes though, such as storing many variables in plaintext or when files need to be shared between other applications.

 

Personally, I feel that XML just means extra steps in getting a file to work correctly, which doesn't make sense when you are going to be storing hardly any data.  (And if you are storing a lot of data, it might be more intuitive to navigate, but it can really balloon the size of a file, as opposed to binary).  My opinion is it is better to just store things in a bin type of file, using something like DataOutputStream.  The benefits being that DataOutputStream is very similar to the PrintWriter, in that once it is setup you just have to change print into things like writeInt....and then use DataInputStream to read in the files using readInt.  That is just my opinion though.

0b10111010 10101101 11110000 00001101

Link to comment
Share on other sites

Link to post
Share on other sites

To be honest, I think too many people put reliance on XML files in Java (I had a teacher who kept pushing for this as well).  The reason why I think XML is overused is that people use it when information isn't going to be passed to other applications.  XML does have it's purposes though, such as storing many variables in plaintext or when files need to be shared between other applications.

 

Personally, I feel that XML just means extra steps in getting a file to work correctly, which doesn't make sense when you are going to be storing hardly any data.  (And if you are storing a lot of data, it might be more intuitive to navigate, but it can really balloon the size of a file, as opposed to binary).  My opinion is it is better to just store things in a bin type of file, using something like DataOutputStream.  The benefits being that DataOutputStream is very similar to the PrintWriter, in that once it is setup you just have to change print into things like writeInt....and then use DataInputStream to read in the files using readInt.  That is just my opinion though.

 

Good. So when information needs to be passed to other applications I should use an XML file?

How would you implement the PrintWriter, or a DataOutputStream? I written some code which works, but I do not really know good ways to implement it. Could you give me an example of a correctly used PrintWriter and/or DataOutputStream? Thank you very much.

Learning

Link to comment
Share on other sites

Link to post
Share on other sites

Personally, I still use bin files when I pass information (but that is because the type of information that I usually pass is known and I need it to be small).  xml is a good way to pass data though (especially if it is something such as a webpage, because then others are able to see the xml and interpret what each value means, in an organized fashion).

 

Well the way you used PrintWriter is basically correct.  A quick example of the DataOutput and DataInput that I use

...			FileOutputStream fos = new FileOutputStream(myFile);//I use a different form of reading in the file, so this line might not work			DataOutputStream dos = new DataOutputStream(fos);			for(i = 0; i < _maxRank; i++) {				dos.writeInt(_names[table][i].length());				dos.writeChars(_names[table][i]);				dos.writeFloat(_highscores[table][i]);			}			fos.close();			dos.close();...
			FileInputStream fis = new FileInputStream(myFile);			DataInputStream dis = new DataInputStream(fis);			for(i = 0; i < _maxRank; i++) {				_names[table][i] = "";				len = dis.readInt();				for(z=0;z<len;z++) //Okay I wrote this when I was really tired, there are better ways to read in a char string 					_names[table][i] += dis.readChar(); //But I haven't found the time to go back and change it								_highscores[table][i] = dis.readFloat();			}			fis.close();			dis.close();

0b10111010 10101101 11110000 00001101

Link to comment
Share on other sites

Link to post
Share on other sites

 

Personally, I still use bin files when I pass information (but that is because the type of information that I usually pass is known and I need it to be small).  xml is a good way to pass data though (especially if it is something such as a webpage, because then others are able to see the xml and interpret what each value means, in an organized fashion).

 

Well the way you used PrintWriter is basically correct.  A quick example of the DataOutput and DataInput that I use

 

 

Very good. Thank you. But, why do you place underscores in front of your variables?

Learning

Link to comment
Share on other sites

Link to post
Share on other sites

Very good. Thank you. But, why do you place underscores in front of your variables?

Oh, it is a habit that I brought over from when I learned to code.

 

When I make a class variables I use underscore, the reason for this is it makes things easier to distinguish.  At a glance (without any IDE formatting), I can easily tell if a variable is local in the method, local in the class, or a constant.  Variables defined within a method are just standard variable names, ones within the class have an underscore infront of them, and constants are all capitalized.  Personally I find this a helpful way to seeing what you are modifying.

 

An example of when it becomes really handy

void changePosition(int x, int y) { //I can see that I am assigning to a class variable, and at the same time the parameters make sense    _x = x;    _y = y;}

It is all about preferences though (and what your company enforces as the standard)

0b10111010 10101101 11110000 00001101

Link to comment
Share on other sites

Link to post
Share on other sites

Oh, it is a habit that I brought over from when I learned to code.

 

When I make a class variables I use underscore, the reason for this is it makes things easier to distinguish.  At a glance (without any IDE formatting), I can easily tell if a variable is local in the method, local in the class, or a constant.  Variables defined within a method are just standard variable names, ones within the class have an underscore infront of them, and constants are all capitalized.  Personally I find this a helpful way to seeing what you are modifying.

 

An example of when it becomes really handy

void changePosition(int x, int y) { //I can see that I am assigning to a class variable, and at the same time the parameters make sense    _x = x;    _y = y;}

It is all about preferences though (and what your company enforces as the standard)

 

Aha really nice. Thank you :)

Learning

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×