Get current line number from bufferedReader - java

I have different text files I would like to read, and I am using BufferedReader for it like this:
int theMax = 0;
int theTypes = 0;
int []theSlices = {};
/*
INPUT1:
17 4
2 5 6 8
INPUT2:
100 10
4 14 15 18 29 32 36 82 95 95
*/
try {
FileReader reader = new FileReader("INPUT1.in");
BufferedReader bufferedReader = new BufferedReader(reader);
String line;
while ((line = bufferedReader.readLine()) != null) {
String[] numbers = line.split(" ");
System.out.println(numbers[0]);
System.out.println(line);
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
;
My problem is that I would like to set the values for theMax, theTypes & theSlices but for that I need to get the current line number and I have no idea how to do that. Reading the file works and println(numbers[0] prints 17 and 2. I am kind of stuck here so I am happy for every help.
Example for INPUT1:
theMax = 17
theTypes = 4
theSlices = 2 5 6 8

Very simple: you keep track yourself.
String line;
int currentLine = 0;
while ((line = bufferedReader.readLine()) != null) {
String[] numbers = line.split(" ");
System.out.println("Linenumber " + currentLine);
System.out.println(numbers[0]);
System.out.println(line);
currentLine ++;
}
reader.close();

Not sure I totally understand what you are after, but for just keeping track of the line numbers, create a variable that you increment in your while loop
i.e.
try {
FileReader reader = new FileReader("INPUT1.in");
BufferedReader bufferedReader = new BufferedReader(reader);
String line;
long currentLineNr = 0;
while ((line = bufferedReader.readLine()) != null) {
currentLineNr++;
String[] numbers = line.split(" ");
System.out.println(numbers[0]);
System.out.println(line);
//Use the currentLineNr how you like
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}

First of all, as far as I know (and having read the official Java documentation for it here - https://docs.oracle.com/javase/8/docs/api/java/io/BufferedReader.html), the BufferedReader class does not in itself give you a mechanism (e.g. a getCurrentLine() method) to determine the current line.
However, there is absolutely nothing stopping you from keeping track of current line number yourself through, say, a counter variable.
Therefore, the relevant section of your code would look like:
int currentLine = 0;
while ((line = bufferedReader.readLine()) != null) {
currentLine++;
String[] numbers = line.split(" ");
/* NOTE: this can be numbers.length >= 2 if you don't care to enforce
having exactly 2 numbers as the first line
*/
if(currentLine == 1 && numbers.length == 2) {
theMax = Integer.valueOf(numbers[0]);
theTypes = Integer.valueOf(numbers[1]);
} else {
for(int index = 0; index < numbers.length; index++) {
theSlices[index] = Integer.valueOf(numbers[index]);
}
}
}
// do something with read values
I would also like to mention that your code could be improved here and there, for example:
You can replace your try with a try-with-resources, such that your readers are managed/closed automatically even if an exception occurs.
If you decide not to use try-with-resources, then you'll need to move your reader.close() method call in a finally block, because if an exception actually occurs you are never closing your resource.
These 2 lines
FileReader reader = ;
BufferedReader bufferedReader = new BufferedReader(reader);
can be simplified into:
BufferedReader bufferedReader = new BufferedReader(new FileReader("INPUT1.in"));
and then you only need to manage the bufferedReader instance if sticking to try instead of try-with-resources.
Hope this helps.
PS: not saying that my code snippet above is perfect, I'm sure it can be written more cleanly

Use java.io.LineNumberReader.
LineNumberReader is a subclass of BufferedReader that keeps track of line numbers. It provides a getLineNumber() method for getting the current line number.
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/io/LineNumberReader.html
Example:
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
public class Example {
public static void main(String[] args) throws IOException {
try (FileReader fr = new FileReader("input.txt");
LineNumberReader r = new LineNumberReader(fr)) {
String next;
while ((next = r.readLine()) != null) {
System.out.println("line number " + r.getLineNumber() + " = " + next);
}
}
}
}

Related

How do I force my while loop that is reading a line to not stop before 3 empty lines?

I have this while loop that is reading a BufferedReader.
BufferedReader br = new BufferedReader(new InputStreamReader(sk.getInputStream()));
String line;
while ((line = br.readLine()) != null) {
System.out.println (line);
}
I know it is going to stop as soon as the line is null, but in this case (the data I am reading), there are some new lines and then the data continues.
Hence, I want the while loop to stop executing once it has found 3 empty lines in a row (for then I am sure that the data is finished).
Thank you
Improving #user2004685's answer, you can count the number of empty lines:
BufferedReader br = new BufferedReader(new InputStreamReader(sk.getInputStream()));
int emptyCount = 0;
String line;
while (emptyCount < 3 && (line = br.readLine()) != null) {
System.out.println (line);
/* Track Empty Lines Count */
if(String.isEmpty(line)) {
emptyCount++;
} else {
emptyCount = 0;
}
}
Don't forget to reset emptyCount to 0, otherwise it'll exit too soon in case you'd have line,emty,line,empty,line,empty,line,empty,line,empty...
Keep a track of the empty lines and add an additional condition to your loop.
Try this piece of code:
BufferedReader br = new BufferedReader(new InputStreamReader(sk.getInputStream()));
int emptyCount = 0;
String line = null;
while (emptyCount < 3 && (line = br.readLine()) != null) {
System.out.println (line);
/* Track Empty Lines Count */
if(String.isEmpty(line)) {
emptyCount++;
} else {
emptyCount = 0;
}
}
Update:
I have overlooked "3 empty lines after each other". Updated the solution as per Gavriel's comment.
Thanks Gavriel!

while(br.readLine() != null)|Window application, java

try {
PrintWriter out = new PrintWriter(new BufferedWriter( new FileWriter("D:\\LOL\\" + choice.getSelectedItem() + "\\KDA.txt", true)));
FileReader fr = new FileReader("D:\\LOL\\" + choice.getSelectedItem() + "\\KDA.txt");
BufferedReader br = new BufferedReader(fr);
String suma ;
while(br.readLine() != null){
Integer.parseInt(suma);
suma = 0; //type mismatch: cannot convert from int to String
suma += Double.parseDouble(br.readLine());
textField_4.setText(suma);
}
} catch (Exception e2) {
}
i know that this loop is bad and just need to make a loop that gonna add all numbers in file and then divide by the number of the numbers. i mean when you have file D:\Lol\Plik\KDA.txt and there is 4,0 2,3 12,7 4,3 (for example) and i need to do a loop : 4,0 +2,3 +12,7+4,3/4 = suma textField_setText(suma);
by using buffered reader
I dont know what you are searching for but you have no Integer variable for Integer.parseInt(suma); and then you set sumato zero. Is that what you want? Additional you parse an empty suma-String.
Here is based on the comments the code-Snippet:
String input = br.readLine();
int sum = 0;
int all = 0;
while(input != null){
sum += Double.parseDouble(su.replace(",", "."));
all++;
input = br.readLine();
}
System.out.println(sum/all);
while (br.readLine() != null)
Stop right there. This is already invalid. You've just read a line and thrown it away. What you need to write is
while ((line = br.readLine()) != null)
and then process line inside the loop.
You're also calling readLine() inside the loop, and without checking it for null. It isn't going to give you the same line twice.

Read first character on each line in a file

I have a file in this format:
0 2 4
3 2 4
3 5 2
1 8 2
My aim is to read the first line on each file and store it in a array. So at the end I should have 0,3,3,1
I thought one approach would be, read the line until we encounter a space and save that in a array...but it would keep on reading 2 and 4 after
Is there a efficient way of doing this, my cod is shown below:
openandprint()
{
int i = 0;
try (BufferedReader br = new BufferedReader(new FileReader("final.txt")))
{
String line;
while ((line = br.readLine()) != null) {
int change2Int=Integer.parseInt(line.trim());
figures [i] = change2Int;
i++;
}
}
catch (Exception expe)
{
expe.printStackTrace();
}
}
Using a Scanner would make the code considerably cleaner:
private static openandprint() throws IOException {
int i = 0;
try (Scanner s = new Scanner("final.txt"))) {
String line;
while (s.hasNextLine()) {
int change2Int = s.nextInt();
s.nextLine(); // ignore the rest of the line
figures [i] = change2Int;
i++;
}
}
}
Try
int change2Int=Integer.parseInt((line.trim()).charAt(0)-'0');
or
int change2Int=Character.getNumericValue(line.charAt(0));
with your approch you are reading the whole line and parsing it to int which will give you NumberFormatException because of the space between the digits.
BufferedReader br = ...;
String line = null;
while ((line = br.readLine()) != null) {
String[] parts = line.split(" ");
int next = Integer.parseInt(parts[0]);
System.out.println("next: " + next);
}

Problems reading a CSV file in Java. Only the first line is read

For a Java homework assignment, I need to create a class that reads and writes CSV files. I'm currently having some problems reading the the CSV. The code below, only outputs the first line of the code and then generates the following error message: 'Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1 at com.gc01.FileManager.CSVManager.main(CSVManager.java:27)".
I have looked at various examples, and I am aware of the 'opencsv' package, but I need to write this code myself. I have located the problem to the statement "System.out.print(data[i]);". However, when cross-referencing this code it all seems to be fine.
I am using the methods from the FileInput class, as specified by my teacher (http://www.devjavasoft.org/SecondEdition/SourceCode/Share/FileInput.java).
public class CSVManager {
public static void main(String [] args){
Scanner sc = new Scanner (System.in);
System.out.println("Please enter the file directory of the chosen CSV");
System.out.println("For Example: /Users/UserName/Downloads/FileName.csv");
///Users/ReeceAkhtar/Desktop/GeoIPCountryWhois.csv
final String fileName = sc.nextLine();
System.out.println("How many columns?");
final int columns = sc.nextInt();
BufferedReader br = null;
String line = "";
String splitBy = " , ";
try {
br = new BufferedReader(new FileReader(fileName));
while((line = br.readLine()) != null) {
for (int i = 0; i < columns; i++) {
String[] data = line.split(splitBy);
System.out.print(data[i]);
}
}
} catch (FileNotFoundException e){
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("File Read");
}
}
Exception is very clear
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
means, you are trying to access 1st element in the array which doesn't exist
Since you are saying System.out.print(data[i]); is the line where the exception is occurring, then for the first line data must have populated with only single element
Debug the issue with IDE to find out why split method is resulting unexpected elements. I suspect usage of spaces around , is the cause in " , "
Try this one. If you take splitting out the for loop everything will be okay.
String[] data = line.split(splitBy);
while((line = br.readLine()) != null){
for (int i = 0; i < columns; i++){
System.out.print(data[i]);
}
}
while((line = br.readLine()) != null){
for (int i = 0; i < columns; i++){
String[] data = line.split(splitBy);
System.out.print(data[i]);
}
You are splitting one line multiple times inside the for loop without any reason.
You are using " , " for splitting (which might be the reason you are having ArrayIndexOfBound exception) Instead use ","; use trim() on data[i] to get rid of trailing/leading white space if you wish to.
After Splitting, put checking whither data.length is equal to columns for consistency.
We are now in the era of JDK 7 where we can use try-with-resource which close the declared resource inside try(){} context, allowing us to get rid of finally block
So your could should look like as follows:
try (BufferedReader br = new BufferedReader(new FileReader(fileName))){
while((line = br.readLine()) != null){
String[] data = line.split(splitBy);
if(data.length != columns)continue; // check for consistency,
//might throw an exception
for (int i = 0; i < columns; i++){
System.out.print(data[i].trim());
}
}catch(IoExection ex)
{
ex.printStackTrace();
}

LineNumberReader Skips the First Line of the file

I am reading the First 6 Lines of a text file with this code:
File finish = new File("C:/ABC Statements final/");
File[] finf = finish.listFiles();
String[] filenames1 = finish.list();
LineNumberReader br = null;
PrintWriter bw = null;
for (int k = 0; k < filenames1.length; k++) {
try {
br = new LineNumberReader(new FileReader(new File("C:/ABC Statements final/" + filenames1[k])));
String line = br.readLine();
while (line != null && br.getLineNumber() <= 6 ) {
line = br.readLine();
System.err.println(line);
}
} catch (Exception asd) {
System.err.println(asd);
}
My Output does not print the first Line of the file. Anyone Who Knows what I am doing wrong?
That's because you're eating up the first line which was read.
String line = br.readLine(); // First line was read here.
while (line != null && br.getLineNumber() <= 6 ) {
line = br.readLine(); // Your first line was overriden here.
System.err.println(line);
}
Make your above code to look something like this:-
String line = null;
while ((line = br.readLine()) != null && br.getLineNumber() <= 6 ) { // Line is read and checked - both together
System.err.println(line);
}
swap these two lines over
line = br.readLine();
System.err.println(line);
so that it is like this
System.err.println(line);
line = br.readLine();
You are calling read twice before the first print.
On line 9 your reading the the first line. This is never printed since you read the second line in the while loop before printing

Categories