How to read specific lines with bufferedReader - java

I need to find some specific data from txt file, see code bellow.
while ((line = bufferedReader.readLine())!= null) {
//pokial obsahuje string zapíš do array
if (line.toLowerCase().contains("list c.")) {
parsedData.add(line);
}
if(line.toLowerCase().startsWith("re")) {
parsedData.add(line);//add found data to array
//i need to access and save second and third line after this one
}
System.out.println(line);
}
In the second condition, when I find a line that starts with "re" I need to save the second and third line after this specific one.

from your question i am not sure but if your target is to get next couple of lines (for example 2) after receiving re at start of line, you can do it by having some flags.
boolean needsToConsider = false;
int countOfLines = 2;
while ((line = bufferedReader.readLine())!= null) {
if(needsToConsider && countOfLines > 0){
// add here
countOfLines--;
if(countOfLines == 0)
needsToConsider = false;
}
//pokial obsahuje string zapíš do array
if (line.toLowerCase().contains("list c.")) {
parsedData.add(line);
}
if(line.toLowerCase().startsWith("re")) {
parsedData.add(line);//add found data to array
//i need to access and save second and third line after this one
needsToConsider = true;
}

A simple approach here might be to just use a counter to keep track of hitting those second and third lines:
int counter = 0;
while ((line = bufferedReader.readLine())!= null) {
if (line.toLowerCase().contains("list c.")) {
parsedData.add(line);
}
else if (line.toLowerCase().startsWith("re")) {
parsedData.add(line);
counter = 2;
}
else if (counter > 0) {
// add second and third lines after "re" here
parsedData.add(line);
--counter;
}
}
A more advanced approach could be to read in the entire portion of text of interest, and then use a regex matcher to extract what you want.

Related

Java ArrayList missing first value

I am taking data from a text file and putting it into an ArrayList. However the first line of the text file is not being printed out.
public static void secondMain() {
BufferedReader reader;
var lines = new ArrayList<String>();
var rooms = new ArrayList<Room>();
try {
reader = new BufferedReader(new FileReader("rooms.txt"));
String line = reader.readLine();
while (line != null) {
line = reader.readLine();
lines.add(line);
}
reader.close();
for (int i = 0; i < lines.size() - 1; i++) {
String[] words = lines.get(i).split(" ");
var room = new Room();
room.RoomNumber = Integer.parseInt(words[0]);
room.Type = (words[1]);
room.Price = Double.parseDouble(words[2]);
room.Bool1 = Boolean.parseBoolean(words[3]);
room.Bool2 = Boolean.parseBoolean(words[4]);
room.Availability = (words[5]);
rooms.add(room);
}
for(int i = 0; i < rooms.size(); i++) {
System.out.println(rooms.get(i).RoomNumber);
System.out.println(rooms.get(i).Type);
System.out.println(rooms.get(i).Price);
System.out.println(rooms.get(i).Bool1);
System.out.println(rooms.get(i).Bool2);
System.out.println(rooms.get(i).Availability);
}
Apologies for the Image, it was the only way i could figure out how to show the formatting of the text file.
The current output is displaying room number 102 as the first room which obviously isn't correct.
If anyone could also help me figure out how to format my console output the same way as the text file that'd also be great. currently it is displaying each individual string/int etc. on a different line.
Thanks.
If you need any more information please just ask!
This has nothing to do with the ArrayList. You can reproduce the problem by replacing the lines.add(line) call with System.out.println(line) and you'll see that the first line is missing from the output. Look at your first call to readLine(), before the while loop. You test that the value is non-null... and that's all you do with it (comments mine):
String line = reader.readLine(); // Read the value...
while (line != null) { // Test for it being non-null
line = reader.readLine(); // Then ignore the value you've just tested,
// by reading the next line.
lines.add(line);
}
You then call readLine() again. Note that your list will always end with a null value (unless it's the first line read) because your loop effectively says "while the last entry I added to the list isn't null". The simplest fix is to swap the order of the statements within your loop:
String line = reader.readLine();
while (line != null) {
lines.add(line);
line = reader.readLine();
}
Now you're adding a line immediately after checking whether it's non-null, before reading the next line.
The problem is here:
String line = reader.readLine(); // you read the first line
while (line != null) {
line = reader.readLine(); // read second line
lines.add(line); // add second line
}
You read the first line, check if it's not null, and then read the second line right away, before you add it to the list. All you need to do is switch the order.
String line = reader.readLine();
while (line != null) {
lines.add(line);
line = reader.readLine();
}

Ignoring blank lines in CSV file in Java

I am trying to iterate through a CSV file in Java. It iterates through the entire file, but will get to the end of the file and try to read the next blank line and throw an error. My code is below.
public class Loop() {
public static void main(String[] args) {
BufferedReader br = null;
String line = "";
try {
HashMap<Integer, Integer> changeData = new HashMap<Integer, Integer>();
br = new BufferedReader(new FileReader("C:\\xxxxx\\xxxxx\\xxxxx\\the_file.csv"));
String headerLine = br.readLine();
while ((line = br.readLine()) != null) {
String[] data = line.split(",");
/*Below is my latest attempt at fixing this,*/
/*but I've tried other things too.*/
if (data[0].equals("")) { break; }
System.out.println(data[0] + " - " + data[6]);
int changeId = Integer.parseInt(data[0]);
int changeCv = Integer.parseInt(data[6]);
changeData.put(changeId, changeCv);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Like I typed, this works fine until it gets to the end of the file. When it gets to the end of the file, I get the error Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0 at com.ucg.layout.ShelfTableUpdates.main(ShelfTableUpdates.java:23). I've stepped through the code by debugging it in Spring Tool Suite. The error comes up whenever I try to reference data[0] or data[6]; likely because there is nothing in that line. Which leads me back to my original question of why it is even trying to read the line in the first place.
It was my understanding that while ((line = br.readLine()) != null) would detect the end of the file, but it doesn't seem to be. I've tried re-opening the file and deleting all of the blank rows, but that did not work.
Any idea how I can detect the end of the file so I don't get an error in this code?
ANSWER:
Credit goes to user #quemeraisc. I also was able to replace the commas with blanks, and if the line then equals null or "", then you know that it is the end of the file; in my case, there are no blank rows before the end of the file. This still does not solve the problem of detecting the end of the file in that if I did have blank rows in between my data that were not the EOF then this would detect those.
Solution 1:
if (data.length < 7) {
System.out.println(data.length);
break;
}
Solution 1:
if (line.replace(",", "").equals(null) || line.replace(",", "").equals("")) {
System.out.println(line.replace(",", ""));
break;
}
Just skip all blank lines:
while ((line = br.readLine()) != null) {
if( line.trim().isEmpty() ) {
continue;
}
....
....
The last line may contain some control characters (like new line, carriage return, EOF and others unvisible chars), in this case a simple String#trim() doesn't remove them, see this answer to know how to remove them: How can i remove all control characters from a java string?
public String readLine() will read a line from your file, even empty lines. Thus, when you split your line, as in String[] data = line.split(","); you get an array of size 1.
Why not try :
if (data.length >= 7)
{
System.out.println(data[0] + " - " + data[6]);
int changeId = Integer.parseInt(data[0]);
int changeCv = Integer.parseInt(data[6]);
changeData.put(changeId, changeCv);
}
which will make sure there are at least 7 elements in your array before proceeding.
To skip blank lines you could try:
while ((line = reader.readLine()) != null) {
if(line.length() > 0) {
String[] data = line.split(",");
/*Below is my latest attempt at fixing this,*/
/*but I've tried other things too.*/
if (data[0] == null || data[0].equals("")) { break; }
System.out.println(data[0] + " - " + data[6]);
int changeId = Integer.parseInt(data[0]);
int changeCv = Integer.parseInt(data[6]);
changeData.put(changeId, changeCv);
}
}
Instead of replace method use replaceAll method. Then it will work.

reversing order of lines in txt file every 'x' number of lines - JAVA

so i have an input txt file where i have to take the first 50 lines and reverse it's order so that the file will start with the 50th line, then the 49th, until the 1st, then continues with the 100th line followed by the 99th, and so on...
but i can only store at most 50 elements. i can't store more than that.
the code i've written so far only grabs the first 50 lines and reverses them, but i dont know how to make it continue on.
this is what i have so far:
ArrayList<String> al = new ArrayList<String>();
int running = 0;
while(running == 0) {
for (String line = r.readLine(); line != null; line = r.readLine()) {
if(al.size() <50 ) {
al.add(line);
}
}
Collections.reverse(al);
for (String text : al) {
w.println(text);
}
if(al.size() < 50) {
break;
}
al.clear();
}
idk why my while loop won't keep running, im only getting the first 50 lines reversed in my output file.
This:
for (String line = r.readLine(); line != null; line = r.readLine()) {
if(al.size() <50 ) {
al.add(line);
}
}
reads all the lines in the file, stores the first fifty in al, and discards the rest. After you then process the results of al, there's nothing more for your program to do: it's read the whole file.
There's a great blog post on how to debug small programs, that I highly recommend: http://ericlippert.com/2014/03/05/how-to-debug-small-programs/
And in your specific case, I suggest breaking your program into functions. One of those functions will be "read up to n lines, and return them in an array-list". This sort of structure makes it easier to reason about each part of the program.
Your initial loop:
for (String line = r.readLine(); line != null; line = r.readLine()) {
if(al.size() <50 ) {
al.add(line);
}
}
Continues to read lines after you've filled al through to the end of the file - it just doesn't put them in the list.
You most likely need something like:
for (String line = r.readLine(); line != null; line = r.readLine()) {
if (al.size() == 50)
outputReverseLines();
al.add(line);
}
outputReverseLines();
Where outputReverseLines is a method that reverses, prints and clears the list.

How to read a text file for particular kind of data?

I have special scenario, in which I am trying to read a file in two while loops . in second loop it reads the file from egining, but I want to read the file where the first while stops reading the file.
Here is my code stuff:
while ((line = br.readLine()) != null) {
if (line.startsWith(rootId.trim())) {
break;
}
}
while (!(line = br.readLine()).contains("---------------------------------------------------")) {
// my other code stuff
}
Here my file stores data as follow,
-----------------------------------------------------
00001# // this is the rootId
N1
N2
-----------------------------------------------------
00002#
N1
N2
-----------------------------------------------------
00003#
N1
N2
This method takes rootId and displays Nodes(N1,N2) and my other stuff. Here my stratergy is to read the file untill I get the rootId after that in another loop untill I get a line (--------) doing my stuff. but in next loop it again starts reading the file from begining . How to solve this. can any help me in this.
while ((line = br.readLine()) != null)
{
if(line.startsWith(rootId.trim()))
{
break;
}
if(!(line = br.readLine()).contains("---------------------------------------------------"))
{
// my other code stuff
}
}
All of your code should be in a single loop, try like this and it should work.
I don't think you need two loops - you should be able to process your file line by line using the first loop and then using if- statements
while ((line = br.readLine()) != null)
{
if(line.startsWith(rootId.trim())||(line.contains("----"))
{
continue;
}
//Process your nodes here - add more if statements if necessary
}
Note that you need
continue;
rather than
break;

java.util.NoSuchElementException: No line found when line exists in file

I have a Code where I am scanning the lines using Scanner Class and looping till there are no lines left.
My code looks like this:
File file = new File(filePath);
if (file.exists()) {
Scanner s = new Scanner(file);
String tmp = null;
int result = 0;
try {
while (true) {
tmp = s.nextLine();
if (tmp != null && tmp.equals("")) {
result += Integer.parseInt(tmp);
}
System.out.println(runSequence(Integer.parseInt(tokens[0])));
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(result);
}
It gives the error at
tmp = s.nextLine();
java.util.NoSuchElementException: No line found
Which is odd because earlier the same code was working fine.
Why is this line giving an error?
Edit:
My mistake i did not state the question correctly, i particularly left the try catch block out of the while loop so that i could make an exit when the lines ended...My question is why am i not able to read any of the lines...i have about 3-4 lines to read in the txt file and it is not reading any and giving exception at the first line read itself...
I think the better way to code is to have a condition in your while loop using Scanner#hasNextLine(). Scanner#hasNextLine() would make sure that code inside while would only run if it has a line in the file=.
while (s.hasNextLine()) {
tmp = s.nextLine();
if (tmp != null && tmp.equals("")) {
result += Integer.parseInt(tmp);
}
if (tmp != null && tmp.equals(""))
should be (if you are trying to check given string is not empty string)
if (tmp != null && !tmp.isEmpty())
I think you reach at the end of file where there is no remaining line and your condition is while(true) so it tries to read that time also . So you getting NoSuchElementException(if no line was found )
So better to change your while loop as
while (s.hasNextLine()){
tmp = s.nextLine();
// then do something
}
while (s.hasNextLine())
{
//...
}

Categories