BufferedReader reads just one line in an multiple line file - java

I tried to archive that a multiline file will be read from an BufferedReader. But this BufferedReader reads just one line and exiting his while(). Before he can read this, another method of the same class should've been written in this file (not at the same time), mostly more than one line. The file contains different types of variables, such as int[], int, double[], String. At the end of one object, or nearly just the data that I've to collect that I can re-calculate the whole object, the ObjectOutputStream pastes "\n". I just write parsed Strings in this file.
In my case, it's a workaround for the ObjectInputStream, cause this stream throws an EOFException every time. For those who don't know the EOFException: it will be thrown if the reader reaches end of file while reading.
I tried to:
set the input string for the BufferedReader to another line
.close() the Reader and make it new
set while(1)
write other Datatypes, such as the whole Object
but all without any changes. The BufferedReader reads just one line and the ObjectInputStream throws EOFException.
LinkedList<SomeAnotherSelfMadeClass> list;
File file = new File(fullPath) // fullPath = absolute path to the file
FileInputStream fileInputStream;
BufferedReader bufferedReader;
public static LinkedList<SomeAnotherSelfMadeClass> readFile()
{
list = new LinkedList<SomeAnotherSelfMadeClass>();
fileInputStream = new FileInputStream(file); // could be FileReader
bufferedReader = new BufferedReader(fileInputStream);
String helper, anotherHelper;
while ((helper = bufferedReader.readLine()) != null)
{
while ((anotherHelper = scanner.hasNext()) != null)
// here's some code with scanner-things, it shouldn't be necessary to
// know. In fact the scanner help to gather the data from the file and
// create an object of SomeAnotherSelfMadeCLass and put it into the list
}
bufferedReader.close();
fileInputStream.close();
return list;
}
What can I do that I can read all lines of the file and re-calcuate my objects that are pasted in there?
I don't know either; it is better to work with the ObjectInputStream or with the BufferedReader? What can I do that the ObjectInputStream don't throws the EOFException (every time I worked with the ObjectInputStream I wrote the whole Object via ObjectOutputStream)?
P.S.: I don't have internet atm at home, so it could take a while that I'm able to answer.

Try with this structure of code..
BufferedReader objReader = null;
public static LinkedList<SomeAnotherSelfMadeClass> readFile()
{
list = new LinkedList<SomeAnotherSelfMadeClass>();
try {
objReader = new BufferedReader(new FileReader(fullPath));
while ((helper= objReader.readLine()) != null) {
...........
System.out.println(helper);//just for checking
while ((anotherHelper = scanner.hasNextLine()) != null){
.....
....
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (objReader != null)
objReader.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}

I'm a little idiot, you have to know.
The second while() had the condition (anotherHelper = scanner.next()) != null, not that what I stated before.
But I managed to get another outputs, even I tried this before (it seems that I'd misstyped at any point);
I set the first while() to true, test helper to break out of the while() and deleted the second while:
while(true)
{
helper = bufferedReader.readLine();
if (helper.equals(null))
break;
// making things with the scanner
}
It seems that the compiler had a problem with this double-while. And optimized it wrong; I think he made
while (((helper = bufferedReader.readLine() != null) && (helper = scanner.nextLine()) != null)
out of this peace of code. That would explain why it only run once and returns true if I test it with System.out.println(scanner.hasNext(); and System.out.println(scanner.hasNextLine(); BEFORE the second while, but in it he returns not even false.

Related

jTextArea saves only first line of text in text file using BufferedReader?

I am trying to save the multiple line output in a text file from my jTextArea(named as "outputarea" in a code) to my desired path, Everything is OK but the file being saved do not contain the whole output, but only first line oof text. I am using "\n" to break the line in jtextarea while giving multiple line output, does that make any difference or any other problem in this code, This code is just the code on saveAs button, output is coming from another methods I've created. Thanks in Advance!
private void saveAs() {
FileDialog fd = new FileDialog(home.this, "Save", FileDialog.SAVE);
fd.show();
if(fd.getFile()!=null)
{
fn=fd.getFile();
dir=fd.getDirectory();
filename = dir + fn +".txt";
setTitle(filename);
try
{
DataOutputStream d=new DataOutputStream(new FileOutputStream(filename));
holdText = outputarea.getText();
BufferedReader br = new BufferedReader(new StringReader(holdText));
while((holdText = br.readLine())!=null)
{
d.writeBytes(holdText+"\r\n");
d.close();
}
}
catch (Exception e)
{
System.out.println("File not found");
}
outputarea.requestFocus();
save(filename);
}
}
You should put the d.close(); after the completion of while loop, because just after writing the first line in the file using DataOutputStream, you are closing it and you don't let it to fulfill the whole job.
You can see even an error is wrote in your console:
File not found
This is not because it doesn't find your file, it's because in the iterations after the first, it tries to write into a closed stream. So only the first line is wrote then. So change you code like this:
while ((holdText = br.readLine()) != null) {
d.writeBytes(holdText + "\r\n");
}
d.close();
Also I can advise to use a PrintWriter instead of DataOutputStream. Then you can easily change the writeBytes into println method. In this way you don't need to append \r\n manually to each line you write.
Another good hint is to use a try-with-resource (in case you use java 7 or later) or at least a finally block to close your streams either way:
String holdText = outputarea.getText();
try (PrintWriter w = new PrintWriter(new File(filename));
BufferedReader br = new BufferedReader(new StringReader(holdText))) {
while ((holdText = br.readLine()) != null) {
w.println(holdText);
}
} catch (Exception e) {
System.out.println("File not found");
}
Good Luck.

JAVA What am I doing wrong, I want the line [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I am trying to make a change log and so I need a single line between some sentences.
All I have is this but it doesn't seem to work. Can anyone help me please?
#Test
public void addLine() {
File temp;
try {
temp = File.createTempFile("app.log", ".tmp", new File("."));
File appLog = new File("app.log");
try (BufferedWriter bw = new BufferedWriter(new FileWriter(temp));
BufferedReader br = new BufferedReader(new FileReader(
appLog))) {
String line;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
if ("2 A".equals(line)) {
bw.write("New Line!");
bw.newLine();
}
}
appLog.delete();
temp.renameTo(appLog);
}
} catch (IOException e) {
e.printStackTrace();
}
}
The problem that you might be encountering might be because of the "line separator" used by the BufferedWriter (it gets set when you create said class). I think it would be best to use instead:
System.getProperty("line.separator");
This way you use the System's line separator rather than a hard coded one.
So that your code would look like this:
public void addLine() {
String lineseparator=System.getProperty("line.separator");
// I'd suggest putting this as a class variable, so that it only gets called once rather
// than
// everytime you call the addLine() method
try {
FileWriter stream = new FileWriter(this.log, true);
//If you don't add true as the second parameter, then your file gets rewritten
// instead of appended to
BufferedWriter out = new BufferedWriter(stream);
out.write(lineseparator); //This substitutes your out.newline(); call
out.close();
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
##############################################################################.
I will try to be as brief and clear as possible.
I assume that you are opening a file that in my code I call "test.txt" and it's got about a paragraph or so. And that you want that outputted to another file, but with "empty lines" at some points.
Because File() is read line by line, it is much easier to open your main file read a line, and then write it to your log file, then analyse if an empty line is necessary and place it.
Let's see some code then.
// Assume you have a private class variable called
private String lineseparator=System.getProperty("line.separator");
// This method is in charge of calling the method that actually carries out the
// reading and writing. I separate them both because I find it is much cleaner
// to have the try{}catch{} blocks in different methods. Though sometimes for
// logging purposes this is not the best choice
public void addLines() {
try {
readAndWrite();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
// This method is in charge of reading one file and output to another.
public void readAndWrite() throws IOException {
File test = new File("test.txt");
FileWriter writer = writer = new FileWriter(new File("log.txt"), true);
//This FileWriter is in charge of writing to your log file
String line;
boolean conditionToWriteNewLine=true;
//Obviously this needs to be changed to suit your situation
// I just added it for show
BufferedReader reader = new BufferedReader( new FileReader (test));
BufferedWriter out = new BufferedWriter(writer);
//It is in this while loop that you read a line
// Analyze whether it needs to have a new line or not
// and then write it out to log file
while( ( line = reader.readLine() ) != null ) {
out.write(line);
if(conditionToWriteNewLine){
out.write(this.lineseparator);
out.write(this.lineseparator);
//You need to write it twice for an EMPTY LINE
}
}
reader.close();
out.close();
}
One of the big differences from this code is that I only open the files once, while in your code you open the log file every time you want to add a new file. You should read the documentation, so you'll know that every time you open the file, your cursor is pointing to the first line, so anything you add will be added to first line.
I hope this helped you understand some more.
I'm not totally sure what you are asking for, but have you tried setting the "append" flag on true, so the FileWriter will not start a new file, but append content to it at the end? This is done by calling the FileWriter(File, boolean) constructor:
public void addLine() {
try {
FileWriter stream = new FileWriter(this.log, true); // Here!
BufferedWriter out = new BufferedWriter(stream);
out.write("New Extra Line Here");
out.newLine();
out.close();
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
I need a single line between some sentences
I guess you mean a new line between other lines of the same file.
To do so you have to read the whole file, locate the place where you want to insert a line, insert the line then write the new content to the file.
This should work fine for small files but if you have large files you might get in trouble.
So you need a more scaleable way of doing it: Read line by line, and write write to a temp file. if you indentify the location where a new line should be inserted, write that line. Continue with the rest of the file. After you are done delete the original file and rename the temp file with the original name.
Pseudocode:
Open actual file
Open temp file
while not end of actual file
Read one line from actual file
Check if new line has to inserted now
Yes: write new line to temp
write line from actual to temp
Close actual file
Close temp file
Delete actual
Rename temp to actual
Code example: (unlike the pseudo code, the new line is inserted after)
Here the line "New Line!" is inserted after each line which is equal to "2 A".
#Test
public void insertNewLineIntoFile() throws IOException {
File temp = File.createTempFile("app.log", ".tmp", new File("."));
File appLog = new File("app.log");
try (BufferedWriter bw = new BufferedWriter(new FileWriter(temp));
BufferedReader br = new BufferedReader(new FileReader(appLog))) {
String line;
while((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
if("2 A".equals(line)) {
bw.write("New Line!");
bw.newLine();
}
}
appLog.delete();
temp.renameTo(appLog);
}
}
Note that File#delete() and File#renameTo both return a boolean value that is true onyl if the operation was successfull. You absolutely need to check those retuned values and handle accordingly.
out.println("\n");
(instead of out.newLine();)
\n in java declares a new line. If you dont add any text before it then it should just print a blank line like you want.
This will work Correctly.
Suggestion:
out.close(); and stream.close(); should write inside finally block ie they should close even if some exceptions occured.

How to read a certain line with a BufferedWriter

I am working on a simple save system for my game, which involves three methods, init load and save.
This is my first time trying out reading and writing to/from a file, so I am not sure if I am doing this correctly, therefore I request assistance.
I want to do this:
When the game starts, init is called. If the file saves does not exist, it is created, if it does, load is called.
Later on in the game, save will be called, and variables will be written to the file, line by line (I am using two in this example.)
However, I am stuck on the load function. I have no idea what do past the point I am on. Which is why I am asking, if it is possible to select a certain line from a file, and change the variable to that specific line.
Here is my code, like I said, I have no idea if I am doing this correctly, so help is appreciated.
private File saves = new File("saves.txt");
private void init(){
PrintWriter pw = null;
if(!saves.exists()){
try {
pw = new PrintWriter(new File("saves.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}else{
try {
load();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void save(){
PrintWriter pw = null;
try {
pw = new PrintWriter(new FileOutputStream(new File("saves.txt"), true));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
pw.println(player.coinBank);
pw.println(player.ammo);
pw.close();
}
public void load() throws IOException{
BufferedReader br = new BufferedReader(new FileReader(saves));
String line;
while ((line = br.readLine()) != null) {
}
}
I was thinking of maybe having an array, parsing the string from the text file into a integer, putting it into the array, and then have the variables equal the values from the array.
Seems like your file is a key=value structure, I suggest you'll use Properties object in java.
Here's a good example.
Your file will look like this:
player.coinBank=123
player.ammo=456
To save:
Properties prop = new Properties();
prop.setProperty("player.coinBank", player.getCoinBank());
prop.setProperty("player.ammo", player.getAmmo());
//save properties to project root folder
prop.store(new FileOutputStream("player.properties"), null);
Then you'll load it like this:
Properties prop = new Properties();
prop.load(new FileInputStream("player.properties"));
//get the property value and print it out
System.out.println(prop.getProperty("player.coinBank"));
System.out.println(prop.getProperty("player.ammo"));
Reading and writing are pretty much symmetric.
You're writing player.coinBank as the first line of the file, and player.ammo as the second line. So, when reading, you should read the first line and assign it to player.coinBank, then read the second line and assign it to player.ammo:
public void load() throws IOException{
try (BufferedReader br = new BufferedReader(new FileReader(saves))) {
player.coinBank = br.readLine();
player.ammo = br.readLine();
}
}
Note the use of the try-with-resources statement here, which makes sure the reader is closed, whatever happens in the method. You should also use this construct when writing to the file.

Read a single file with multiple BufferedReaders

I'm working on a program that needs to update a line that depends its value on the result of a line that goes read after. I thought that I could use two BufferedReaders in Java to position the reader on the line to update while the other one goes for the line that fixes the value (it can be an unknown number of lines ahead). The problem here is that I'm using two BufferedReaders on the same file and even if I think I'm doing right with the indexes the result in debug doesn't seem to be reliable.
Here's the code:
String outFinal
FileName=fileOut;
File fileDest=new File(outFinalFileName);
try {
fout = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream(fileDest)));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
FileReader inputFile=null;
try {
inputFile = new FileReader(inFileName);
} catch (FileNotFoundException e2) {
e2.printStackTrace();
}
BufferedReader fin = new BufferedReader(inputFile);
BufferedReader finChecker = new BufferedReader(inputFile); //Checks the file and matches record to change
String line="";
String lineC="";
int lineNumber=0;
String recordType="";
String statusCode="";
try {
while ((lineC = finChecker.readLine()) != null) {
lineNumber++;
if (lineNumber==1)
line=fin.readLine();
recordType=lineC.substring(0,3);//Gets current Record Type
if (recordType.equals("35")){
while(!line.equals(lineC)){
line=fin.readLine();
if (line==null)
break;
fout.write(line);
}
}else if (recordType.equals("32")){
statusCode=lineC.substring(4,7);
if(statusCode.equals("XX")){
updateRecordLine(line,fout);
}
}
}
returnVal=true;
} catch (IOException e) {
e.printStackTrace();
}
Thanks in advance.
Well, the BufferedReader only reads stuff, it doesn't have the ability to write data back out. So, what you would need is a BufferedReader to get stuff in, and a BufferedWriter that takes all the input from the BufferedReader, and outputs it to a temp file, with the corrected/appended data.
Then, when you're done (i.e. both BufferedReader and BufferedWriter streams are closed), you need to either discard the original file, or rename the temp file to the name of the original file.
You are basically copying the original file to a temp file, modifying the line in question in the temp file's output, and then copying/renaming the temp file over the original.
ok, i see some problem in your code exactly on these lines-->
recordType=lineC.substring(0,3);//Gets current Record Type
if (recordType.equals("35")){
if you see on the first line, you are getting the substring of recordType into recordType. Now recordType length is 3. If at all the recordType has only 2 characters, then substring throws arrayIndexOutOfBoundsException. So when no runtime exceptions, its length is 3 and on the next line you are calling the equals method that has a string with 2 characters.
Will this if block ever run ?

How Can I Reset The File Pointer to the Beginning of the File in Java?

I am writing a program in Java that requires me to compare the data in 2 files. I have to check each line from file 1 against each line of file 2 and if I find a match write them to a third file. After I read to the end of file 2, how do I reset the pointer to the beginning of the file?
public class FiFo {
public static void main(String[] args)
{
FileReader file1=new FileReader("d:\\testfiles\\FILE1.txt");
FileReader file2=new FileReader("d:\\testfiles\\FILE2.txt");
try{
String s1,s2;
while((s1=file1.data.readLine())!=null){
System.out.println("s1: "+s1);
while((s2=file2.data.readLine())!=null){
System.out.println("s2: "+s2);
}
}
file1.closeFile();
file2.closeFile();
}catch (IOException e) {
e.printStackTrace();
}
}
}
class FileReader {
BufferedReader data;
DataInputStream in;
public FileReader(String fileName)
{
try{
FileInputStream fstream = new FileInputStream(fileName);
data = new BufferedReader(new InputStreamReader(fstream));
}
catch (IOException e) {
e.printStackTrace();
}
}
public void closeFile()
{
try{
in.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
I believe RandomAccessFile is what you need. It contains: RandomAccessFile#seek and RandomAccessFile#getFilePointer.
rewind() is seek(0)
I think the best thing to do would be to put each line from file 1 into a HashMap; then you could check each line of file 2 for membership in your HashMap rather than reading through the entire file once for each line of file 1.
But to answer your question of how to go back to the beginning of the file, the easiest thing to do is to open another InputStream/Reader.
Obviously you could just close and reopen the file like this:
while((s1=file1.data.readLine())!=null){
System.out.println("s1: "+s1);
FileReader file2=new FileReader("d:\\testfiles\\FILE2.txt");
while((s2=file2.data.readLine())!=null){
System.out.println("s2: "+s2);
//compare s1 and s2;
}
file2.closeFile()
}
But you really don't want to do it that way, since this algorithm's running time is O(n2). if there were 1000 lines in file A, and 10000 lines in file B, your inner loop would run 1,000,000 times.
What you should do is read each line and store it in a collection that allows quick checks to see if an item is already contained(probably a HashSet).
If you only need to check to see that every line in file 2 is in file 1, then you just add each line in file one to a HashSet, and then check to see that every line in file 2 is in that set.
If you need to do a cross comparison where you find every string that's in one but not the other, then you'll need two hash sets, one for each file. (Although there's a trick you could do to use just one)
If the files are so large that you don't have enough memory, then your original n2 method would never have worked anyway.
well, Gennady S. answer is what I would use to solve your problem.
I am writing a program in Java that requires me to compare the data in 2 files
however, I would rather not code this up again.. I would rather use something like http://code.google.com/p/java-diff-utils/
As others have suggested, you should consider other approaches to the problem. For the specific question of returning to a previous point in a file, java.io.FileReader would appear to inherit mark() and reset() methods that address this goal. Unfortunately, markSupported() returns false.
Alternatively, BufferedReader does support mark(). The program below prints true, illustrating the effect.
package cli;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class FileReaderTest {
public static void main(String[] args) {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(
new FileInputStream("src/cli/FileReaderTest.java")));
in.mark(1);
int i1 = in.read(); in.read(); in.read();
in.reset();
int i2 = in.read();
System.out.println(i1 == i2);
} catch (IOException e) {
e.printStackTrace(System.err);
}
}
}
As noted, there are better algorithms - investigate these
aside:
FileReader doesn't implement mark and reset, so trashgod's comments are inaccurate.
You'd either have to implement a version of this (using RandomAccessFile or what not) or wrap in a BufferedReader. However, the latter will load the whole thing in memory if you mark it
Just a quick Question. can't you keep one object pointed at the start of the file and traverse through the file with another object? Then when you get to the end just point it to the object at the beginning of the file(stream). I believe C++ has such mechanisms with file I/O ( or is it stream I/O)
I believe that you could just re-initialize the file 2 file reader and that should reset it.
If you can clearly indentify the dimension of your file you can use mark(int readAheadLimit) and reset() from the class BufferedReader.
The method mark(int readAhedLimit) add a marker to the current position of your BufferedReader and you can go back to the marker using reset().
Using them you have to be careful to the number of characters to read until the reset(), you have to specify them as the argument of the function mark(int readAhedLimit).
Assuming a limit of 100 characters your code should look like:
class MyFileReader {
BufferedReader data;
int maxNumberOfCharacters = 100;
public MyFileReader(String fileName)
{
try{
FileInputStream fstream = new FileInputStream(fileName);
data = new BufferedReader(new InputStreamReader(fstream));
//mark the current position, in this case the beginning of the file
data.mark(maxNumberOfCharacters);
}
catch (IOException e) {
e.printStackTrace();
}
}
public void resetFile(){
data.reset();
}
public void closeFile()
{
try{
in.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
If you just want to reset the file pointer to the top of the file, reinitialize your buffer reader. I assume that you are also using the try and catch block to check for end of the file.
`//To read from a file.
BufferedReader read_data_file = new BufferedReader(new FileReader("Datafile.dat"));'
Let's say this is how you have your buffer reader defined. Now, this is how you can check for end of file=null.
boolean has_data= true;
while(has_data)
{
try
{
record = read_data_file.readLine();
delimit = new StringTokenizer(record, ",");
//Reading the input in STRING format.
cus_ID = delimit.nextToken();
cus_name = delimit.nextToken();'
//And keep grabbing the data and save it in appropriate fields.
}
catch (NullPointerException e)
{
System.out.println("\nEnd of Data File... Total "+ num_of_records
+ " records were printed. \n \n");
has_data = false; //To exit the loop.
/*
------> This point is the trouble maker. Your file pointer is pointing at the end of the line.
-->If you want to again read all the data FROM THE TOP WITHOUT RECOMPILING:
Do this--> Reset the buffer reader to the top of the file.
*/
read_data_file = new BufferedReader(new FileReader(new File("datafile.dat")));
}
By reinitializing the buffer reader you will reset the file reader mark/pointer to the top of the file and you won't have to recompile the file to set the file reader marker/pointer to beginning/top of the file.
You need to reinitialize the buffer reader only if you don't want to recompile and pull off the same stunt in the same run. But if you wish to just run loop one time then you don't have to all this, by simply recompiling the file, the file reader marker will be set to the top/beginning of the file.

Categories