Adding number of lines with BufferedWriter/Reader - java

Please help me with adding number of lines of original file.
Im trying to write lines which met specified conditions from file A to file B. There is no problem, but I need to write number of lines of file A to the end of file B and also add number of lines of file B.
Program runs through file A, if condition is met, line is written to the file B, however I stuck to add number of lines after that.
For the last 2 hours I already tried second BufferedWriter, second "try" block, bw.write(lines) and many more, but nothing worked. System.out.println(lines) worked good, so Im really confused.
Here's my actual code:
try (
BufferedReader bReader = new BufferedReader(new FileReader("fileA.txt"));
BufferedWriter bWriter = new BufferedWriter(new FileWriter("fileB.txt"));
LineNumberReader lineNumberReader = new LineNumberReader(new FileReader("fileA.txt"));
){
lineNumberReader.skip(Long.MAX_VALUE);
int lines = lineNumberReader.getLineNumber();
lineNumberReader.close();
String line;
while ((line = bReader.readLine()) != null){
String[] values = line.split(" ");
int time = Integer.parseInt(values[3]);
if (time < 16){
bWriter.write(values[0] + ' ' + values[1] + ' ' + values[2] + "\n");
}
}
}

You can do that by adding bWriter.write(""+lines); after while loop.
You have to use bWriter.write(string) instead of bWriter.write(int).
bWriter.write(string) - the string value is written to the file as is.
bWriter.write(int); - It won't work because the int passed is converted to corresponding char and is then written to the file. The char corresponding to your lines value must be some non-printable character, and hence you are not able to see it.

Related

Read from file with BufferedReader

Basically I've got an assignment which reads multiple lines from a .txt file.
There are 4 values in the text file per line and each value is separated by 2 spaces.
There are about 10 lines of data in the file.
After taking the input from the file the program then puts it onto a Database. The database connection functionality works fine.
My issue now is with reading from the file using a BufferedReader.
The issue is that if I uncomment any 1 of the 3 lines at the bottom the BufferedReader reads every other line. And if I don't use them then there's an exception as the next input is of type String.
I have contemplated using a Scanner with the .hasNextLine() method.
Any thoughts on what could be the problem and how to fix it?
Thanks.
File file = new File(FILE_INPUT_NAME);
FileReader fr = new FileReader(file);
BufferedReader readFile = new BufferedReader(fr);
String line = null;
while ((line = readFile.readLine()) != null) {
String[] split = line.split(" ", 4);
String id = split[0];
nameFromFile = split[1];
String year = split[2];
String mark = split[3];
idFromFile = Integer.parseInt(id);
yearOfStudyFromFile = Integer.parseInt(year);
markFromFile = Integer.parseInt(mark);
//line = readFile.readLine();
//readFile.readLine();
//System.out.println(readFile.readLine());
}
Edit: There was an error in the formatting of the .txt file. a missing value.
But now I get an ArrayOutOfBoundsException.
Edit edit: Another error in the .txt file! Turns out there was a single space instead of a double. It seems to be working now. But any advice on how to deal with file errors like this in the future?
The issue is that if I uncomment any 1 of the 3 lines at the bottom the BufferedReader reads every other line.
Correct. If you put any of those lines of code in, the line of text read will be thrown away and not processed. You're already reading in the while condition. You don't need another read. If you put any of those lines in, they will be thrown away and not proce
A compilable version of the code posted could be
public void read() throws IOException {
File file = new File(FILE_INPUT_NAME);
FileReader fr = new FileReader(file);
BufferedReader readFile = new BufferedReader(fr);
String line;
while ((line = readFile.readLine()) != null) {
String[] split = line.split(" ", 4);
if (split.length != 4) { // Not enough tokens (e.g., empty line) read
continue;
}
String id = split[0];
String nameFromFile = split[1];
String year = split[2];
String mark = split[3];
int idFromFile = Integer.parseInt(id);
int yearOfStudyFromFile = Integer.parseInt(year);
int markFromFile = Integer.parseInt(mark);
//line = readFile.readLine();
//readFile.readLine();
//System.out.println(readFile.readLine());
}
}
The above uses a single space (" " instead of the original " "). To split on any number of changes, a regular expression can be used, e.g. "\\s+". Of course, exactly 2 spaces can also be used, if that reflects the structure of the input data.
What the method should do with the extracted values (e.g., returning them in an object of some type, or saving them to a database directly), is up to the application using it.

Java 6: Copy and manipulate files

What I want to do...
I have XML-Files with names like SomeName999999blablabla.xml with lots of content, where almost every line contains the string "999999". I need identical xml-files where 999999 is replaced by 888888, 777777, and so on, in the name and the file's content.
The problem...
My code works fine and actually creates all the files I need, BUT there are sometimes tiny errors. Like in one line an E is "randomly" replaced by a D (it seems to be always one letter lower than what its supposed to be, but I can't confirm that 100%). Its not a lot, like one or two instances in 60 files, each file being about 100MB. But since its an xml this is a real problem, as this often is a schema violation, which causes a crash in later processing.
I have absolutely no idea where this is coming from or how to fix it, please help.
My code so far...
private void createMandant(String mandant) throws Exception {
String line;
File dir = new File(TestConstants.getXmlDirectory());
for (File file : dir.listFiles()) {
if (file.getName().endsWith((".xml")) && file.getName().contains("999999")) {
BufferedReader br = new BufferedReader(new FileReader(file));
FileWriter fw = new FileWriter(file.getAbsolutePath().replace("999999", mandant));
while ((line = br.readLine()) != null) {
fw.write(line.replace("999999", mandant) + "\r\n");
}
br.close();
fw.close();
}
}
}
Environment...
We are on Java 6. As mentioned before the files are quite large. Like 100MB, several hundred thousand lines each.
It appears to be a problem with String.replace()
I have replaced it with StringBuilder:
while ((line = br.readLine()) != null) {
index = 0;
// fw.write(line.replace("999999", mandant) + "\r\n");
StringBuilder builder = new StringBuilder(line);
index = builder.indexOf("999999");
if (index > 0) {
fw.write(builder.replace(index, index + 6, mandant).toString() + "\r\n");
} else {
fw.write(line + "\r\n");
}
}
... and now it seems to work. Two runs have already completed without any problems.
But that seems very strange. Could it really be that a heavily used function like String.replace() just randomly gets single letters wrong every few million method calls?

Returning the number of lines in a .txt file

This is my debut question here, so I will try to be as clear as I can.
I have a sentences.txt file like this:
Galatasaray beat Juventus 1-0 last night.
I'm going to go wherever you never can find me.
Papaya is such a delicious thing to eat!
Damn lecturer never gives more than 70.
What's in your mind?
As obvious there are 5 sentences, and my objective is to write a listSize method that returns the number of sentences listed here.
public int listSize()
{
// the code is supposed to be here.
return sentence_total;}
All help is appreciated.
To read a file and count its lines, use a java.io.LineNumberReader, plugged on top of a FileReader. Call readLine() on it until it returns null, then getLineNumber() to know the last line number, and you're done !
Alternatively (Java 7+), you can use the NIO2 Files class to fully read the file at once into a List<String>, then return the size of that list.
BTW, I don't understand why your method takes that int as a parameter, it it's supposed to be the value to compute and return ?
Using LineNumberReader:
LineNumberReader reader = new LineNumberReader(new FileReader(new File("sentences.txt")));
reader.skip(Long.MAX_VALUE);
System.out.println(reader.getLineNumber() + 1); // +1 because line index starts at 0
reader.close();
use the following code to get number of lines in that file..
try {
File file = new File("filePath");
BufferedReader reader = new BufferedReader(new FileReader(file));
String line;
int totalLines = 0;
while((line = reader.readLine()) != null) {
totalLines++;
}
reader.close();
System.out.println(totalLines);
} catch (Exception ex) {
ex.printStackTrace(System.err);
}
You could do:
Path file = Paths.getPath("route/to/myFile.txt");
int numLines = Files.readAllLlines(file).size();
If you want to limit them or process them lazily:
Path file = Paths.getPath("route/to/myFile.txt");
int numLines = Files.llines(file).limit(maxLines).collect(Collectors.counting...);

The structure of txt file code is reading from

can anybody please explain why there have to be exactly 3 empty rows in between sections of text (marked with number) in the txt file my code is reading from ?
I have a code that is reading lines from txt file. The structure of the file is as follows:
1
r
line of text
line of text
line of text
line of text
line of text
2
a
line of text
line of text
line of text
line of text
line of text
A number is a mark that i m using to identify which section to read. When section is identified my code then reads consecutive lines of text and returned values are assigned to String variables.
All works perfectly only and only if there is exactly 3 empty rows separating each section of text is source txt file. I d like to understand why is it so ? Thank you very much
Here's the snippet of my code:
inpStream = getClass().getResourceAsStream("/resources/myFile.txt");
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inpStream,"UTF-16BE"))){
do{
num = Integer.toString(a);
line = reader.readLine();
if(line.equals(num)){
who = reader.readLine();
what = reader.readLine();
sat = reader.readLine();
pow = reader.readLine();
satNo = reader.readLine();
cash = reader.readLine();
break;
}
} while(!line.equals(num) && (line = reader.readLine()) != null );
}
catch(IOException e){}
It is the number and order of calls to readLine().
Your code reads and checks every other line for a match. The three blank lines are not important, it's just that it's an even number since the first index number. It will also work with one, five etc.
The double read occurs once at the beginning of each iteration, and once in the condition.
line = reader.readLine();
and
while(... && (line = reader.readLine()) != null
Thereby skipping two lines each iteration.
I would recommend either moving the first read out of the loop, or change to a while-loop:
String line;
while ((line = reader.readLine() != null) {
if (line.equals(num){
...
break;
}
}
This reads each line, checking against num for each line.
Defining num can also be moved out of the loop, as it does not change inside the loop. Giving a full example of:
InputStream inpStream = getClass().getResourceAsStream("/resources/myFile.txt");
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inpStream, "UTF-8"))) {
num = Integer.toString(a);
String line;
while ((line = reader.readLine()) != null) {
if (line.equals(num)) {
who = reader.readLine();
what = reader.readLine();
sat = reader.readLine();
pow = reader.readLine();
satNo = reader.readLine();
cash = reader.readLine();
break;
}
}
} catch (IOException e) {
}
Note: This example uses UTF-8.
You have to read all the lines whether you need them or not. You can't pretend you read lines, that you didn't. You can skip the lines after the ones you needed.
Lets break up your code line by line and analyze.
Line 1.
You call the getClass() function on an InputStream object which in turn you use to call the getStreamResource() function to return a "stream" to your file data.
Now having access to this stream you enclose your BufferReader in a try/catch statement.
Line2.
next you create a BufferReader with Reader Parameter inpstream and file encoding type UFT-16.
Line 3-13
You haven't shown me where you have declared 'a' so I can't be sure, but you are converting an integer 'a' to a string called num. (This is important because it is the terminating factor of your do statement.) I am assuming a =1 in the first iteration.
Now its all about understanding File Offsets.
when you say
line=reader.readLine();
this returns a String containing the current line characters and sets the file offset to the next line.
your file offset is at 'r' (for 1st iteration).
The same technique for reading who,what,sat,pow,satNo & cash.
Now your while statement checks if both conditions are true or not. i.e line != num (which it is since you haven't redefined num anywhere after reading who,what,sat,pow,satNo & cash.) And also line=line.readLine() != null which is also true.
However here is your first mistake calling line=reader.readLine() the way you did this increments the file offset one more line. Thus in two iterations two lines are read in addition to what you expect. This messes up the order in which you envisioned your variables to be found i.e who,what,sat,pow,satNo & cash etc in your do statement.
Therefore in short you are skipping every other line after your first iteration.
You need to get rid of one of your readLine calls.
The two double counting are:
line = inpstream.readLine() and
line = reader.readLine()) != null

Reading data from a specific line and counting words from nth line to print nth word on that line

I have this program that reads a text file. I need to get some data out of it.
The text files look like this:
No. Ret.Time Peak Name Height Area Rel.Area Amount Type
min µS µS*min % mG/L
1 2.98 Fluoride 0.161 0.028 0.72 15.370 BMB
2 3.77 Chloride 28.678 3.784 99.28 2348.830 BMB
Total: 28.839 3.812 100.00 2364.201
I need to start reading from line #29 and from there get the Peak Name and the Amount of each element like Fluoride, Chloride and so on. The example only shows those two elements, but other text files will have more. I know I will need some sort of loop to iterate through those lines starting on line #29 which is where the "1" starts then the "2" which will be the 30th line and so on.
I have tried to make this work, but I am missing something I think and I`m not sure what. Here is my Code.
int lines = 0;
BufferedReader br = new BufferedReader(new FileReader(selectFile.getSelectedFile()));
Scanner sc = new Scanner(new FileReader(selectFile.getSelectedFile()));
String word = null;
while((word =br.readLine()) != null){
lines++;
/*if(lines == 29)
System.out.println(word);*/
if ((lines == 29) && sc.hasNext())
count++;
String value = sc.next();
if (count == 2)
System.out.println(value + ",");
}
Here's some code for you:
int linesToSkip = 28;
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String line;
while ( (line = br.readLine()) != null) {
if (linesToSkip-- > 0) {
continue;
}
String[] values = line.split(" +");
int index = 0;
for (String value : values) {
System.out.println("values[" + index + "] = " + value);
index++;
}
}
}
Note that I've surrounded it in a try(expr) {} block to ensure that the reader is closed at the end, otherwise you'll consume resources and possibly lock the file from other processes.
I've also renamed the variable you called word as line to make it clearer what it contains (i.e. a string representing a line in the file).
The line.split(" +") uses a regular expression to split a String into its constituent values. In this case your values have spaces between, so we're using " +" which means 'one or more spaces'. I've just looped through the values and printed them out; obviously, you will need to do whatever it is you need to do with them.
I replaced the line count with a linesToSkip variable that decrements. It's less code and explains better what you're trying to achieve. However, if you need the line number for some reason then use that instead, as follows:
if (++lineCount <= 28) {
continue;
}
If I'm reading it correctly, you are mixing two different readers with the BufferedReader and the Scanner, so you are not going to get the results right changing from one to the other (one is not pointing to the same position than the other). You already have the line in word and you can parse it, no need of using the Scanner. Just skip until line 29 (lines > 29) and then parse the values you want, line by line.
You are reading the file twice... try something like this
int lines = 0;
BufferedReader br = new BufferedReader(new FileReader(selectFile.getSelectedFile()));
String line = null;
while ((line = br.readLine()) != null) {
if (++lines < 29)
continue; //this ignores the line
for(String word : line.split("separator here")) {
// this will iterate over every word on that line
// I think you can take it from here
System.out.println(word);
}
}

Categories