Buffered Output Writing to File Wrong - java

I can't figure it out. I'm trying to write out text from my program. It's suppose to a word count program. Show me the number of lines, characters, word count. Then I display the results along with the word the user is searching for and that line.
(i.e. searching java)
line 5: the island of java contains Java
line 9: I love to drink java
It's not displaying text. Its displaying like heiroglyphics.
Line 2: DN{c�<���\$H�Uz�X����h4[����bA.�D��Ja�8^)|��k�ˠ����<Τ���QJ�����P˒��nI"�(��vc�Bi�"&�/�|qI�W6{pa�0��[���[M��;�FU�!}4�x�����{�-��(����V�k#�We֭Tʺ
Line 3: �N�U �������Ӣ ͇�?�
Line 4: Ӻ鬵�P��D<�}L>��o�V�Ex���Q|�)�'��g�I�B�3b�(�"3�T�7��� �=��s�g�F�;KN���r��_�� ʺ:�� �B�ۢ�s��sP����[6��; �� PK ! ��� N _rels/.rels �(�
public void readFromFile(String filename)
{
LineNumberReader lineNumberReader = null;
try {
lineNumberReader = new LineNumberReader(new FileReader(filename));
String line = null;
BufferedWriter output = new BufferedWriter(new FileWriter("output.txt"));
String ask = "Enter Word";
String find = JOptionPane.showInputDialog(ask);
Scanner scan = new Scanner(new File("test.txt"));
while ((line = lineNumberReader.readLine()) != null)
{
line = scan.nextLine();
if(line.indexOf(find) >= -1)
{
output.write("Line " + lineNumberReader.getLineNumber() +
": " + line);
output.newLine();
}
}// end of while
output.close();
} // end of try
catch (FileNotFoundException ex)
{
ex.printStackTrace();
}
catch (IOException ex)
{
ex.printStackTrace();
}
finally {
try {
if (lineNumberReader != null)
{
lineNumberReader.close();
}
} // end of try
catch (IOException ex)
{
ex.printStackTrace();
}
}// end of finally
} // end of function

I don't get why you are doing this :
while ((line = lineNumberReader.readLine()) != null)
{
line = scan.nextLine();
if(line.indexOf(find) >= -1)
{
output.write("Line " + lineNumberReader.getLineNumber() +
": " + line);
output.newLine();
}
}// end of while
instead of this :
while ((line = lineNumberReader.readLine()) != null)
{
if(line.indexOf(find) >= -1)
{
output.write("Line " + lineNumberReader.getLineNumber() +
": " + line);
output.newLine();
}
}// end of while
You don't need 2 readers for this. And I don't understand why one of the reader is reading in a final file and the other one is reading from a file which name is coming from arg

The default OS encoding is used as set in System.getProperty("file.encoding").
You can explicitly pick one.
final String encoding = "UTF-16LE"; // Or "Cp1252" or "UTF-8"
lineNumberReader = new LineNumberReader(new InputStreamReader(new FileInputStream(filename), encoding));
...
BufferedWriter output = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("output.txt"), encoding));
...
Scanner scan = new Scanner(new File("test.txt", encoding));

Related

Saving Game Scores

i am trying to make a highscore for a hangman game. So i need to save it so it doesnt restart everytime u start the game or return to the menu.. so I have a playstate that records the wins and losses at the end of the game and if the user leaves before solving it adds a loss. I found a tutorial to save via a SavaData file.. the problem is it saves an empty file nothing in there but has 2 empty lines.. and so i get a numberformatexception null.. i had it working before but it still would not read the line and would return an error numberformatexception Integer.parseInt.. I know the problem is in reading lines and now i dont know what went wrong please help me .. whats wrong with the code?? thanx
this is the saving code...
private void createSaveData() {
File file = new File(saveDataPath, filename);
try {
FileWriter output = new FileWriter(file);
BufferedWriter writer = new BufferedWriter(output);
writer.write("" + 0);
writer.newLine();
writer.write("" + 0);
} catch (Exception e) {
e.printStackTrace();
}
}
private void setScores() {
FileWriter output = null;
try {
File F = new File(saveDataPath, filename);
output = new FileWriter(F);
BufferedWriter writer = new BufferedWriter(output);
writer.write(wins);
writer.newLine();
writer.write(losses);
writer.close();
}catch (Exception e){
e.printStackTrace();
}
}
private void loadScores() {
try {
File F = new File(saveDataPath, filename);
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(F)));
String line = reader.readLine();
line = reader.readLine();
wins = Integer.parseInt(line);
line = reader.readLine();
losses = Integer.parseInt(line);
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
i then add loadScore(); at the begging of the playstate.. and setScore(); after a win++ or a loss++..
i have another highscorestate that calls on playstate and gets the wins and lossess as an integer and that works no problems cause it draws 0 , 0 .
in my render method i have this if the tries are too much or if the correct answer is guessed...
if (tries == 6) {
currentWord = ranWord;
execcurrentframe.setRegion(eman.ExecLoss.getKeyFrame(elapsedTime, false));
hangcurrentframe.setRegion(hman.hangdead.getKeyFrame(elapsedTime, false));
Wordsfont.draw(batch, "Game Over", eman.getPosition().x + 60, hman.getPosition().y + 70);
batch.draw(fu, 160, 510);
if (leverpressed == false){
bksound.stop();
lever.play();
leverpressed = true;
}
if (lossrecorded == false) {
losses += 1;
System.out.print("Losses = " + losses);
setScores();
lossrecorded = true;
}
}
else if (CorrectAnswer == true) {
hangcurrentframe.setRegion(hman.hangwin.getKeyFrame(elapsedTime, false));
Wordsfont.draw(batch, "You Won", eman.getPosition().x + 60, hman.getPosition().y + 70);
if (winrecorded == false) {
bksound.stop();
victory.play();
wins += 1;
System.out.print("Wins = " + wins);
setScores();
winrecorded = true;
}
}
I would suggest the following changes.
Use a single writeSaveData method. The code between createSaveData and setScores is largely duplicated. Also, use the Integer.toString() to write the output. Also, ensure the stream is closed (here using try with resources).
private void writeSaveData(int wins, int losses)
{
File file = new File(saveDataPath, filename);
try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
writer.write(Integer.toString(wins));
writer.newLine();
writer.write(Integer.toString(losses));
}
catch (Exception e) {
e.printStackTrace();
}
}
There is an extra readLine() in the loadScores() method. Remove that extra line. Change to use try with resources.
private void loadScores()
{
File file = new File(saveDataPath, filename);
try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)))) {
String line = reader.readLine();
// line = reader.readLine() <-- REMOVE THIS LINE
wins = Integer.parseInt(line);
line = reader.readLine();
losses = Integer.parseInt(line);
reader.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
EDIT: If one cannot use try with resources, then the following approach may be used instead.
private void loadScores()
{
File file = new File(saveDataPath, filename);
BufferedReader reader = null;
// try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)))) {
try {
reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
String line = reader.readLine();
wins = Integer.parseInt(line);
line = reader.readLine();
losses = Integer.parseInt(line);
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if (reader != null) {
try {
reader.close();
}
catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
}
A similar modification may be made to the suggested writeSaveData() or other methods.
You have overlooked one important part of the original createSaveData method:
writer.write("" + 0);
See that "" + 0? It effectively converts the integer to a string (though there are more elegant ways of doing this).
BufferedWriter has overloaded write method. This means there is a different method that is called when the parameter is a String, and a different one when the parameter is an int.
You have called the version whose parameter is an int. Its documentation says:
public void write(int c) throws IOException
Writes a single character.
Overrides:
write in class Writer
Parameters:
c - int specifying a character to be
written
Throws:
IOException - If an I/O error occurs
This tells you that it considers the int that you passed as a character. That is, if you give it the int 65, it will be taken as the character A. If you give it the int 48, it will be taken as the character 0.
If you give it the integer 0, this is the NUL control character.
When you read that back as a string, it is taken as a single-character string containing the NUL character. Of course, that's not a valid string format for a number.
So replace
writer.write(wins);
With
writer.write(String.valueOf(wins));
And do the same for losses.

Can't write all list to the file

I have an ArrayList list of some lines from text file. I am trying to find these lines in a text file, if I find it I want to write it to another text file and delete it from the original file.
I wrote a code for that, it is working but not for the whole list, sometimes take one line and sometimes take more. and give me this message:
1 R101 100850 0
Exception caught : java.io.IOException: Stream closed
static void moveLines(ArrayList posList, int topic) {
//=======================To read lines=======
File inputFile = new File("U:\\Research\\Projects\\sef\\enhancfeaturtm\\TestData\\topic\\" + "Test" + topic + ".txt");
File outputFile = new File("U:\\Research\\Projects\\sef\\enhancfeaturtm\\TestData\\topic\\" + "Training" + topic + ".txt");
try {
FileReader fr = new FileReader(inputFile);
BufferedReader br = new BufferedReader(fr);
FileWriter fr1 = new FileWriter(outputFile);
BufferedWriter writer = new BufferedWriter(fr1);
String line;
int count = 1;
int z = 1;
while ((line = br.readLine()) != null) {
// System.out.println(z++ + ": ");
String subLine = line.substring(5, line.length() - 2);
// System.out.println(subLine);
if (posList.contains(subLine)) {
System.out.println(count++ + " " + line);
fr1.write(line);
fr1.write("\n");
fr1.flush();
fr.close();
removeLineFromFile(inputFile.getAbsolutePath(), line);
}
}
br.close();
fr1.close();
writer.close();
} catch (Exception e) {
System.out.println("Exception caught : " + e);
}
}
static void removeLineFromFile(String file, String lineToRemove) {
try {
File inFile = new File(file);
//Construct the new file that will later be renamed to the original filename.
File tempFile = new File(inFile.getAbsolutePath() + ".tmp");
BufferedReader br = new BufferedReader(new FileReader(file));
PrintWriter pw = new PrintWriter(new FileWriter(tempFile));
String line = null;
//Read from the original file and write to the new
//unless content matches data to be removed.
while ((line = br.readLine()) != null) {
if (!line.trim().equals(lineToRemove)) {
pw.println(line);
pw.flush();
}
}
pw.close();
br.close();
//Delete the original file
if (!inFile.delete()) {
System.out.println("Could not delete file");
return;
}
//Rename the new file to the filename the original file had.
if (!tempFile.renameTo(inFile)) {
System.out.println("Could not rename file");
}
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
Can someone help me please?
String subLine = line.substring(5, line.length() - 2);
You are hard coding to take substring from index 5.
What happens when the length of line is less than 5? have a check if the line's length is less than 5 and only then proceed.
Also why are catching with 'Exception' ? try catching with a lower level exception like ArrayIndexOutOfBoundsException etc.
Thank you all for your help.
I figure out the problem, it was because I delete the file and create it again from temp file. in that case I lose the pointer to the file.
This is the code after I fix it if someone interested.
static void moveLines(ArrayList posList, int topic) {
//=======================To read lines=======
File inputFile = new File("U:\\Research\\Projects\\sef\\enhancfeaturtm\\Data1\\topic\\" + "Test" + topic + ".txt");
File outputFile = new File("U:\\Research\\Projects\\sef\\enhancfeaturtm\\Data1\\topic\\" + "Training" + topic + ".txt");
try {
FileReader fileReader = new FileReader(inputFile);
BufferedReader bufferedReader = new BufferedReader(fileReader);
FileWriter fileWriter = new FileWriter(outputFile);
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
String line;
while ((line = bufferedReader.readLine()) != null) {
String subLine = line.substring(5, line.length() - 2);
if (posList.contains(subLine)) {
System.out.println(count++ + " " + line);
bufferedReader.close();
fileReader.close();
bufferedWriter.write(line+"\n");
bufferedWriter.flush();
bufferedReader = removeLineFromFile(inputFile.getAbsolutePath(), line);
}
}
bufferedWriter.close();
fileWriter.close();
bufferedReader.close();
fileReader.close();
} catch (Exception e) {
System.out.println("Exception caught : " + e);
}
}
static BufferedReader removeLineFromFile(String file, String lineToRemove) {
BufferedReader bufferedReader = null;
try {
File inFile = new File(file);
//Construct the new file that will later be renamed to the original filename.
File tempFile = new File(inFile.getAbsolutePath() + ".tmp");
BufferedReader br = new BufferedReader(new FileReader(file));
BufferedWriter bw = new BufferedWriter(new FileWriter(tempFile));
String line = null;
//Read from the original file and write to the new
//unless content matches data to be removed.
while ((line = br.readLine()) != null) {
if (!line.trim().equals(lineToRemove)) {
bw.write(line+"\n");
bw.flush();
}
}
bw.close();
br.close();
//Delete the original file
if (!inFile.delete()) {
System.out.println("Could not delete file");
return null;
}
//Rename the new file to the filename the original file had.
if (!tempFile.renameTo(inFile)) {
System.out.println("Could not rename file");
}
FileReader fileReader = new FileReader(inFile);
bufferedReader = new BufferedReader(fileReader);
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
return bufferedReader;
}

Reading and writing arraylist to textfile

I'm having a problem with reading and writing arraylist to a text file. Specifically with reading. What I'm trying to do is read from a text file and transfer it to an array list. After which i would edit the list and write it back to the text file. I think I go the writing done but not the reading. I've tried reading several similar questions here but cant seem to inject it into my code.
Reading code
public void read(List<AddressBook> addToList){
BufferedReader br = null;
try {
String currentLine= "";
br = new BufferedReader(new FileReader("bank_account.csv"));//file na gusto mo basahin
while ((currentLine = br.readLine()) != null) {
System.out.println(currentLine); // print per line
for (AddressBook read : addToList) {
br.read(read.getName() + read.getAddress() + read.getTelNum() + read.getEmailAdd());
addToList.add(read);
} }
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null)
{
br.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
Here's what I've done with the write
public void write(List<AddressBook> addToList) {
try {
File file = new File("bank_account.csv"); //file
// if file doesnt exists, then create it
if (!file.exists()) {
file.createNewFile();
}
//FileWriter fw = new FileWriter(file.getAbsoluteFile());
FileWriter fw = new FileWriter(file.getAbsoluteFile(), true);
BufferedWriter bw = new BufferedWriter(fw);
for (AddressBook write : addToList) {
bw.write(write.getName() + "," + write.getAddress() + "," + write.getTelNum() + "," + write.getEmailAdd());
bw.newLine();
}
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
while ((currentLine = br.readLine()) != null) {
System.out.println(currentLine); // print per line
for (AddressBook read : addToList) {
br.read(read.getName() + read.getAddress() + read.getTelNum() + read.getEmailAdd());
addToList.add(read);
}
}
I bet in there you will need to do something like:
reading each line
parsing it (each line is a CSV)
creating a new AddressBook object with all that info
add it to the collection
The code for that will look like:
while ((currentLine = br.readLine()) != null) {
System.out.println(currentLine); // print per line
String[] splitted = currentLine.split(",");
AddressBook address = new AddressBook(splitted[0], splitted[1], splitted[2], splitted[3]);
addToList.add(address);
}
Of course there are things you will need to check and validate, but that is roughtly it.
Maybe you need read method like this.
public void read() {
List<AddressBook> addToList =new ArrayList<AddressBook>();
BufferedReader br = null;
try {
String currentLine= "";
br = new BufferedReader(new FileReader("bank_account.csv"));//file na gusto mo basahin
while ((currentLine = br.readLine()) != null) {
System.out.println(currentLine); // print per line
// for (AddressBook read : addToList) {
String[] split =currentLine.split(",");
AddressBook read = new AddressBook();
read.setName(split[0]);
read.setAddress(split[1]);
read.setTelNum(split[2]);
read.setEmailAdd(split[3]);
// br.read(read.getName() + read.getAddress() + read.getTelNum() + read.getEmailAdd());
addToList.add(read);
// }
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null)
{
br.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}

BufferedReader - count lines containing a string

I am using a .txt file that contains: "Hello world\nHow are you doing this day?" I want to count whether a line contains a string or not, as well as the total number of lines. I use:
File file = new File(file_Path);
try {
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
int i=0;
int j=0;
while ((line = br.readLine()) != null) {
j++;
if (line.contains("o")) { //<----------
i++;
}
}
System.out.print("Lines containing the string: " + i + " of total lines " + j-1);
As I run and test line.contains("o"), it prints 2 lines containing "o", which is correct as well as 2 total lines. As I run line.contains("world"), it prints 0 lines which is wrong but gives 2 lines total. But what do I do wrong?
I tested it with a StringReader,
String str = "Hello world\nHow are you doing this day?";
StringReader sr = new StringReader(str);
try {
BufferedReader br = new BufferedReader(sr);
String line;
int i = 0;
int j = 0;
while ((line = br.readLine()) != null) {
j++;
if (line.contains("world")) { // <----------
i++;
}
}
System.out
.println("Lines containing the string: " + i
+ " of total lines " + j);
} catch (Exception e) {
e.printStackTrace();
}
Your file contents must not be what you think because I get
Lines containing the string: 1 of total lines 2
As the others answers and comments, I also think you may not be reading the file you think you are... (Relax it happens to everyone from time to time)
But, also it could be the encoder of the file or the version of the jdk you have, maybe if you could answer:
What did you use to create the file?
What OS you are running
this?
What JDK are you using?
It could clarify what may have happened
Just for you to know, I ran the same code you have using jdk8 and worked fine for me.
As follows the test I did:
1) I put your code in a function:
int countLines(String filename, String wording) {
File file = new File(filename);
String line;
int rowsWithWord = 0;
int totalRows = 0;
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
while ((line = br.readLine()) != null) {
totalRows++;
if (line.contains(wording)) {
rowsWithWord++;
}
}
} catch (IOException e) {
System.out.println("Error Counting: " + e.getMessage());
}
System.out.println(String.format("Found %s rows in %s total rows", rowsWithWord, totalRows));
return rowsWithWord;
}
2) and ran the following unit test
#Test
public void testFile() {
try (FileWriter fileWriter = new FileWriter(new File("C:\\TEMP\\DELETE\\Hello.txt"));
BufferedWriter writer = new BufferedWriter(fileWriter)) {
writer.write("Hello world\nHow are you doing this day?");
} catch (IOException e) {
System.out.println("Error writing... " + e);
}
int countO = fileUtils.countLines("C:\\TEMP\\DELETE\\Hello.txt", "o");
Assert.assertEquals("It did not find 2 lines with the letters = o", 2, countO);
int countWorld = fileUtils.countLines("C:\\TEMP\\DELETE\\Hello.txt", "world");
Assert.assertEquals("It did not find 1 line with the word = world", 1, countWorld);
}
And I got the expected result:
Found 2 rows in 2 total rows
Found 1 rows in 2 total rows

Only prints out last line to the text file and not the rest in java

I am trying to print a file to the text file. Although I have managed to make it work, it only prints out the last line that is printed on the console. E.g. My console has around 8000 lines but it only prints out the last line in the text file, and I want to print all the lines into the text file.
This is the code:
try {
BufferedReader reader = new BufferedReader(new FileReader("JDT.txt"));
Writer output = null;
File file = new File("output.txt");
output = new BufferedWriter(new FileWriter(file));
String line = reader.readLine();
int count=0;
while(line !=null)
{
for(int i = 0 ; i<faults.length;i++){
if(line.contains(faults[i]))
System.out.println(line);
count++;
output.write(line +"Total: "+count);
//System.out.println("File Written");
}
line=reader.readLine();
}
System.out.println("Printed Lines =" +count);
output.close();
}
catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
}
Thank you in advanced.
You are re-creating and overwriting your file in each loop. Create your file and your BufferedWriter before your loops, and close it after your loops finish.
You should place these lines before the beginning of the while loop.
Writer output = null;
File file = new File("output.txt");
output = new BufferedWriter(new FileWriter(file));
And close the Writer after while loop exits.
output.close();
Also the statement output.write(line +"Total: "+count); is trying to write every line at the end of another, resulting in one big line of output. Replace it with:
output.write(line + "Total: " + count + "\n");
This should result in each line getting printed on a new line.
Not sure if it's expected but in your code output.write might get executed multiple times for the same line depending on the length of your faults variable. This will result in same line getting printed more than once.
If the length of the faults is n the write will be called n times for the same line.
I think you need this:
while (line != null) {
for (int i = 0; i < faults.length; i++) {
if (line.contains(faults[i])) {
count++;
output.write(line + "Total: " + count + "\n");
System.out.println(line);
break;
}
}
// System.out.println("File Written");
line = reader.readLine();
}
I thought I'd put this here for reference. It's just a general approach for copying lines from an input file to an output file.
final class Sample
{
private static final String inputFile = "input_file.txt";
private static final String outputFile = "output_file.txt";
public void start()
{
BufferedReader bufferedReader;
BufferedWriter bufferedWriter;
try
{
bufferedReader = new BufferedReader(new FileReader(inputFile));
bufferedWriter = new BufferedWriter(new FileWriter(outputFile));
copyContents(bufferedReader, bufferedWriter);
bufferedReader.close();
bufferedWriter.close();
}
catch (final IOException e)
{
e.printStackTrace();
}
}
private void copyContents(final BufferedReader bufferedReader, final BufferedWriter bufferedWriter)
{
try
{
String line = bufferedReader.readLine();
while (null != line)
{
bufferedWriter.write(line + '\n');
line = bufferedReader.readLine();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}

Categories

Resources