I have a program and one of the methods I use is for counting the lines a .txt file has and return an integer value. The problem is when I execute it, despite I wrote if my line is == null the while has to stop, the while loop keeps going, ignoring the nulls it gets infinitely.
I don't know what to do to try to solve it.
private int sizeOfFile (File txt) {
FileReader input = null;
BufferedReader count = null;
int result = 0;
try {
input = new FileReader(txt);
count = new BufferedReader(input);
while(count != null){
String line = count.readLine();
System.out.println(line);
result++;
}
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
input.close();
count.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
return result;
}
It has to stop when it detects a null, which means there are no more lines, but it keeps going.
When you instantiate a BuffereReader assign it to count, count will always be non-null and hence will satisfy the while loop:
count = new BufferedReader(input); //count is holding an instance of BufferedReader.
while(count != null){ //here count is non-null and while loop is infinite and program never exits.
Instead use the following code, where the each line will be read and checked whether it is null, if null then the program will exit.:
input = new FileReader(txt);
count = new BufferedReader(input);
String line = null;
while(( line = count.readLine())!= null){ //each line is read and assigned to the String line variable.
System.out.println(line);
result++;
}
If you are using JDK-1.8 you can shorten your code using the Files API:
int result = 0;
try (Stream<String> stream = Files.lines(Paths.get(txt.getAbsolutePath()))) {
//either print the lines or take the count.
//stream.forEach(System.out::println);
result = (int)stream.count();
} catch (IOException e) {
e.printStackTrace();
}
count is your BufferedReader, your loop should be on line! Like,
String line = "";
while (line != null) {
line = count.readLine();
Also, you should use try-with-Resources to close your resources (instead of the finally block). And you could write that while loop more idiomatically. Like,
private int sizeOfFile(File txt) {
int result = 0;
try (BufferedReader count = new BufferedReader(new FileReader(txt))) {
String line;
while ((line = count.readLine()) != null) {
System.out.println(line);
result++;
}
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
return result;
}
Related
I wanted to return an object within a method that has a try-catch block. As shown below the method takes in a CSV file, reads the serialNumber and is supposed to return an object of the book with attributes such as name, year, etc., from the CSB file. I want to just return this object but I don't know where in the scope to return it given that foundName is local and thus I won't be able to return the new object r.
public static ReadCSVExample1 readBook(String filename, String serialNumber){
try{
String line = "";
BufferedReader br = new BufferedReader(new FileReader(filename));
String foundName = "";
while ((line = br.readLine()) != null){
String[] values = line.split(",");
for (int z = 0; z<values.length; z++){
if (values[z].equals(serialNumber)){
System.out.println(values[z]+ " found!");
foundName = values[z+1];
System.out.println(values[z+2]);
System.out.println(values[z+3]);
}
}
}
} catch (FileNotFoundException e){
System.err.println(e);
} catch (IOException e){
System.err.println(e);
}ReadCSVExample1 r = new ReadCSVExample1(foundName);
return r;
}
Just move the foundName outside the try-catch block like so:
public static ReadCSVExample1 readBook(String filename, String serialNumber){
String foundName = "";
try{
String line = "";
BufferedReader br = new BufferedReader(new FileReader(filename));
while ((line = br.readLine()) != null){
String[] values = line.split(",");
for (int z = 0; z<values.length; z++){
if (values[z].equals(serialNumber)){
System.out.println(values[z]+ " found!");
foundName = values[z+1];
System.out.println(values[z+2]);
System.out.println(values[z+3]);
}
}
}
} catch (FileNotFoundException e){
System.err.println(e);
return null;
} catch (IOException e){
System.err.println(e);
return null;
}ReadCSVExample1 r = new ReadCSVExample1(foundName);
return r;
}
If it's not outside the try-catch block, the scope of foundName is within the try-catch block. If you move it outside, it's scope is the entire method.
I'm reading from a text file which looks like this:
1
The Adventures of Tom Sawyer
2
Huckleberry Finn
4
The Sword in the Stone
6
Stuart Little
I have to make it so that the user can enter the reference number and the program will perform binary and linear search and output the title. My teacher said to use two ArrayLists, one for the numbers and one for the titles, and output from them. I just can't figure out how to skip lines so I can add to the corresponding arraylist.
int number = Integer.parseInt(txtInputNumber.getText());
ArrayList <String> books = new ArrayList <>();
ArrayList <Integer> numbers = new ArrayList <> ();
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("bookList.txt"));
String word;
while ((word = br.readLine()) != null ){
books.add(word);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
Thanks in advance, I appreciate any help!
You can check if you are in even or odd lines by doing a modulo 2 operation on the line number:
try (BufferedReader br = new BufferedReader(new FileReader("bookList.txt"))) {
String word;
int lineCount = 0;
while ((word = br.readLine()) != null ){
if (++lineCount % 2 == 0) {
numbers.add(Integer.parseInt(word));
} else {
books.add(word);
}
}
} catch (IOException e) {
e.printStackTrace();
}
int number = Integer.parseInt(txtInputNumber.getText());
ArrayList <String> books = new ArrayList <>();
ArrayList <Integer> numbers = new ArrayList <> ();
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("bookList.txt"));
String word;
while ((word = br.readLine()) != null ){
numbers.add(Integer.valueOf(word));
word = br.readLine()
books.add(word);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
You could make check to see if it is actually a integer, that you read from the file. As far as I remember, there is no built in method to do this, but you can define your own as:
boolean tryParseInt(String value) {
try {
Integer.parseInt(value);
return true;
} catch (NumberFormatException e) {
return false;
}
}
Then just make a check to see if the line you have read in is a integer or not.
int number = Integer.parseInt(txtInputNumber.getText());
ArrayList <String> books = new ArrayList <>();
ArrayList <Integer> numbers = new ArrayList <> ();
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("bookList.txt"));
String word;
while ((word = br.readLine()) != null ){
if (tryParseInt(word))
numbers.add(Integer.parseInt(word))
else
books.add(word);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
Hope this help!
I want to extract the first String in a file using the delimiter ",".
Why does this code generate a number of lines greater than one?
public static void main(String[] args) {
BufferedReader in = null;
try {
in = new BufferedReader(new FileReader("irisAfter.txt"));
String read = null;
while ((read = in.readLine()) != null) {
read = in.readLine();
String[] splited = read.split(",");
for (int i =0; i<splited.length;i++) {
System.out.println(splited[0]);
}
}
} catch (IOException e) {
System.out.println("There was a problem: " + e);
e.printStackTrace();
} finally {
try {
in.close();
} catch (Exception e) { e.printStackTrace(); }
}
}
You are printing inside a loop. That's why it is printing multiple times (if that's what you're asking).
String[] splited = read.split(",");
System.out.println(splited[0]);
will just do
EDIT: As Abishek also mentioned, don't read = in.readLine(); again inside your while loop since by doing so you are skipping a line.
while ((read = in.readLine()) != null) {
String[] splited = read.split(",");
System.out.println(splited[0]);
}
What do you mean by number of lines superior to the original ones
If you are using splited[0], why are you keeping inside a loop. It will always get you same string
Not sure why your code works that way but you might try Scanner with a delimeter. Try:
Scanner sc = new Scanner( new File("myNumbers")).useDelimiter(",");
String firstString = sc.next();
/// check for null..
You read in every line from "irisAfter.txt", then split each line on "," into multiple elements, then print out the first element of that line on its own line as many times as there are elements in the line. Multiple lines*multiple elements per line = more lines in output than in input.
Change
for (int i =0; i<splited.length;i++) {
System.out.println(splited[0]);
}
to
if (splited.length > 0)
{
System.out.println(splited[0]);
}
That way you print out the first element of every line on its own line only one time and only if there actually is a first element.
You are also skipping every other line. If you don't want to do that, remove the line
read = in.readLine();
just below
while ((read = in.readLine()) != null) {.
(You are now reading in a line and then reading in the next line, discarding the first read in line. Then you process that second line, after which the loop starts again, you read in the third line, then read in the fourth line, discarding the third, etc. etc.)
if you modify your code like this, you should get the result you expect.
public static void main(String[] args) {
BufferedReader in = null;
try {
String[] splited;
in = new BufferedReader(new FileReader("irisAfter.txt"));
String read = null;
while ((read = in.readLine()) != null) {
read = in.readLine();
splited = read.split(",");
}
System.out.println(splited[0]);
} catch (IOException e) {
System.out.println("There was a problem: " + e);
e.printStackTrace();
} finally {
try {
in.close();
} catch (Exception e) {
}
}
}
I have a variable that is set in a while loop because it is reading from a file. I need to access and use the code from the outside of the loop, because I'm using the variable in an if statement and the if statement can't be in the while loop or else it will be repeated multiple times. Here is my code.
BufferedReader br = null;
try {
String sCurrentLine;
br = new BufferedReader(new FileReader("C:\\Users\\Brandon\\Desktop\\" + Uname + ".txt"));
while ((sCurrentLine = br.readLine()) != null) {
System.out.println(sCurrentLine);
}if(sCurrentLine.contains(pwd)){System.out.println("password accepted");}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null)br.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
Put your if statement inside your for loop, but use a break:
while...
if(sCurrentLine.contains(pwd)){
System.out.println("password accepted");
break;
}
This breaks out of the for loop, so that once the password is found, it stops looping. You can't really move that if-check outside of the loop, because you want to check every line for the password until it is found, right?
If you do that, you don't need to move the sCurrentLine variable out of the loop. You also might want to doublecheck if you want to do sCurrentLine.equals(pwd) instead of using contains.
You already have sCurrentLine declared outside your while loop. The problem is that you keep using it again and again for the next line. If you still want it to print the file and what you are trying to do is remember that the password was found or what line it was found in try this:
BufferedReader br = null;
boolean pwdFound = false;
String pwdLine = "";
try {
String sCurrentLine;
br = new BufferedReader(new FileReader("C:\\Users\\Brandon\\Desktop\\" + Uname + ".txt"));
while ((sCurrentLine = br.readLine()) != null) {
System.out.println(sCurrentLine);
if(sCurrentLine.contains(pwd)){
System.out.println("password accepted");
pwdFound = true;
pwdLine = sCurrentLine;
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null)br.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
boolean flag = false;
while ((sCurrentLine = br.readLine()) != null) {
if(sCurrentLine.contains(pwd))
{
flag = true;
break;
}
}
if(flag){System.out.println("password accepted");}
If I am scanning from a text
Scanner s= new Scanner("texto.txt");
// I want to compare the next char from the line with a <
// like this:
if(s.nextChar().equals("<")){
.....
I know that s.nextChar() does not exist but there is any similar thing to use in this case?
Your code would something like...
Scanner s= new Scanner("texto.txt");
s.useDelimiter("");
while (s.hasNext()) {
if(s.nextChar()=='<'){
.....
}
Note that after the call of s.nextChar(), the value is actually fetched, so its better to keep the variable, if you would like to use it further, like:
char ch = s.nextChar();
Consider dumping Scanner and using FileReader:
FileReader fileReader = new FileReader("textto.txt");
int charRead
while( (charRead = fileReader.read()) != -1)
{
if(charRead == '<')
{
//do something
}
}
FileReader reader = null;
try {
reader = new FileReader("");
int ch = reader.read() ;
while (ch != -1) {
// check for your char here
}
} catch (FileNotFoundException ex) {
//
} catch (IOException ex) {
//
} finally {
try {
reader.close();
} catch (IOException ex) {
//
}
}