I'm writing some code in Java to scan through a .txt file. Each line in the file contains two tokens, and there's only about 7 rows of data.
My aim is to use the while loop to scan through each line, store the tokens in a HashMap, and when the scanner reaches the end of the document I want the while loop to terminate. Here is a snippet of the code I am using:
while ((line = b.readLine()) != null) {
s = new Scanner(line);
String fileName = s.next();
String source = s.next();
sourceMap.put(fileName, source);
}
This is something I have done many times before, however there are now some issues with the while loop terminating. The while loop continues to operate even after the 'final' line has been read. When the scanners attempt to read tokens, a java.util.NoSuchElementException is returned.
From using the debugger I can see that the line immediately after the 'final' line of code is being read as: ""
I believe this is an empty string, however I am unsure if this is different to a line being null. I attempted to add code for the condition while (line != "") however this did not result in the while loop being terminated.
Has anyone experienced similar issues before, and if so how did you overcome them?
EDIT: This has now been resolved. There was a line with an empty string after the 'final' line in the .txt file. The corrected code is as follows:
while ((line != null) && (!line.isEmpty())) {
s = new Scanner(line);
String fileName = s.next();
String source = s.next();
sourceMap.put(fileName, source);
line = b.readLine();
}
Related
Can anyone tell me why my code never reads the 2nd line of my file? if my 2nd line in the file (for example .txt file) start at a new line and indent that line, it will not read it.But if it is in a new line and it isn't indented , it will read. also it reads 3rd line fine. Is it something with the while loop ?
Scanner keyboard = new Scanner (System.in);
System.out.println("Input the file name");
String fileName = keyboard.nextLine();
File input = new File (fileName);
BufferedReader reader = new BufferedReader(new FileReader(input));
String content = reader.readLine();
content.replaceAll("\\s+","");
while (reader.readLine() != null) {
content = content + reader.readLine();
}
System.out.println(content);
See my comments in the code below.
String content = reader.readLine(); //here you read a line
content.replaceAll("\\s+","");
while (reader.readLine() != null) //here you read a line (once per loop iteration)
{
content = content + reader.readLine(); //here you read a line (once per loop iteration)
}
As you can see, you are reading the second line in the beginning of your while loop, and you are checking if it is equal to null before moving on. However, you do nothing with that value, and it is lost. A better solution would look like this:
String content = ""
String input = reader.readLine();
while (input != null)
{
content = content + input;
input = reader.readLine();
}
This avoids the problem of reading and then throwing away every other line by storing the line in a variable and checking the variable for null instead.
Each time you call readLine() it reads the next line. The statement
while (reader.readLine() != null)
reads a line but does not do anything with it. What you want is
String line;
StringBuilder buf;
while ( (line = reader.readLine()) != null)
{
buf.append(line);
}
content = buf.toString();
Using a StringBuilder is much better as it avoids reallocating and copying the entire string each time you append.
I have a text file that I can now scan, however there are certain lines within the file that I don't want to read in, is there a way to only read in a line if it starts with a capital letter?
Please help a nooby?
Pretty straightforward problem, pretty simple solution:
try (BufferedReader br = new BufferedReader(new FileReader("filename.txt"))) {
String line;
while ((line = br.readLine()) != null) {
if(!line.isEmpty() && Character.isUpperCase(line.charAt(0)))
System.out.println(line);
}
}
catch(Exception e){
// Handle the trouble
}
Simply check if the line you just read (provided non-empty and not null as checked in the if-statement) starts with an uppercase letter, otherwise it will move on to the next line.
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
I have several strings in a file where I am supposed to stop and read the values from those strings. For example:
This is the first line
#1 stop = 300
This is the third line
This is the 4th line
#2 stop = 400
This is the 6th line
I need to stop at #1 and extract the value 300 from there. Then I have to stop at #2 and extract 400, and so on.
I am VERY new to Java and can't figure out what is wrong with my code. (I haven't gotten to extracting the values yet):
public static void main(String[] args) throws IOException {
//read
File fromFile = new File("in.txt");
BufferedReader bufferedReader = new BufferedReader(new FileReader(fromFile));
String line;
String firstHandler="";
while ((line = bufferedReader.readLine()) != null) {
bufferedReader.readLine();
if (firstHandler.startsWith("#1")){
System.out.println(firstHandler);
String[] parts = firstHandler.split("=");
System.out.println(Arrays.toString(parts));
}
break;
}
System.out.println(line);
bufferedReader.close();
}
}
At this point it only prints the first line, which is not at all what I need. Can anyone explain to me how this should be done in the right way?
The errors are in these 4 lines:
String firstHandler="";
while ((line = bufferedReader.readLine()) != null) {
bufferedReader.readLine();
if (firstHandler.startsWith("#1")){
You read one line from inside the while statement. And for each line read, you enter the block. But inside this block, you read yet another line.
And then, what you compare with "#1" is not the line that you have just read, but firstHandler, which is initialized as an empty string once, and never modified. The code should be:
while ((line = bufferedReader.readLine()) != null) {
if (line.startsWith("#1")) {
The reader should also be closed in a finally block, but that's another matter.
First of all, as pointed out in the comments, you need to match lines starting with a #, since there are multiple lines beginning with # but having a different second character.
Next, you need to check the value of the line that you are reading to check for the # character. So, you can get rid of the firstHandler variable and use the line variable instead.
Finally, you need to get rid of the break statement, since that causes the loop to exit after the first line itself. That is the reason you only see the first line on the screen.
Therefore, your code can be changed to something like this:
while ((line = bufferedReader.readLine()) != null)
{
if (line.startsWith("#"))
{
System.out.println(line);
String[] parts = line.split("=");
System.out.println(Arrays.toString(parts));
}
}
I need help with this. Can you tell me how to calculate the number of lines in the input.txt without counting the empty space lines?
So far, I tried:
BufferedReader reader = new BufferedReader(new FileReader("input.txt"));
int lines = 0;
while (reader.readLine() != null)
lines++;
So, this code is able to count the number of lines, but with the empty lines! I know that there are characters /n which illustrates the new line but I do not know how to integrate it in the solution.
I also tried to calculate number of lines, number of empty lines and subtract them, but I wasn't successful.
BufferedReader reader = new BufferedReader(new FileReader("input.txt"));
int lines = 0;
String line;
while ((line = reader.readLine()) != null){
if(!"".equals(line.trim())){
lines++;
}
}
You just need to remember the line you're looking at, and check it before counting:
int lines = 0;
String line;
while ((line = reader.readLine()) != null) {
if (!line.isEmpty()) {
lines++;
}
}
Note that you should be closing your reader too - either in an explicit finally statement, or using a try-with-resources statement in Java 7. I'd advise not using FileReader, too - it always uses the platform default encoding, which isn't a good idea, IMO. Use FileInputStream with an InputStreamReader, and state the encoding explicitly.
You might also want to skip lines which consist entirely of whitespace, but that's an easy change to make to the if (!line.isEmpty()) condition. For example, you could use:
if (!line.trim().isEmpty())
instead... although it would be cleaner to find a helper method which just detected whether a string only consisted of whitespace rather than constructing a new string. A regex could do this, for example.
BufferedReader's readLine() method only returns null when the end of the stream has been reached. To not count empty lines, test if the line exists and if it's empty then don't count it.
Quoting the linked Javadocs above:
Returns:
A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached
Clean and fast.
try (BufferedReader reader = new BufferedReader("Your inputStream or FileReader")) {
nbLignes = (int) reader.lines().filter(line -> !line.isEmpty()).count();
}