I'm not entirely sure what the issue is, but here is a snippet of my code. I get the warning for my line variable
StringBuffer stringBuffer = new StringBuffer();
String line = "" ;
while(( line = bufferedReader.readLine()) != null ){
stringBuffer.append(line);
}
The warning simply means that the empty string with which the line variable is initialized is useless.
Before line is read, it is being assigned in the loop declaration:
line = bufferedReader.readLine()
So assigning line = "" is redundant. You can leave it uninitialized:
String line;
while((line = bufferedReader.readLine()) != null) {
stringBuffer.append(line);
}
Append to #ernest_k answer, assigning line = "" is redundant only if you reassign line with another value and you don't use line in return statement or set statement (set value need at least null value).
Related
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));
}
}
So I tracked down the bugger, but I am no closer to understanding what is wrong. Here is what the compiler says:
Exception in thread "main" java.lang.NullPointerException at
BasicFile.Search(BasicFile.java:215) at
TestFile.main(TestFile.java:42)
Line 215 is the one that starts with while, first one.
String Search(String key) throws IOException {
int lines = 0;
String line = "";
String foundAt = "";
BufferedReader BF = new BufferedReader(new FileReader(f));
try {
while ((line = BF.readLine().toLowerCase()) != null) {
lines++;
//create tokenizer words with what is in line
StringTokenizer words = new StringTokenizer(line);
while(words.hasMoreTokens()) { //while words has tokens left
//go to next token and compare to key
if (words.nextToken().equals(key.toLowerCase()))
foundAt = foundAt + "\n" + lines + ":" + line;
//do nothing continue loop
}
}
BF.close();
} catch(FileNotFoundException e) {
}
return foundAt;
}
When your buffer reader runs out of lines it returns null. You are trying to call toLowerCase method on null which ends up throwing the null pointer exception.
Refactor your code in a way that it doesn't require you to execute toLowerCase before ensuring the line is non-null.
For example:
String next;
while ((next = BF.readLine()) != null) {
String line = next.toLowerCase();
// ...
}
while ((line = BF.readLine().toLowerCase()) != null)
What happens if BF.readline() returns null?
remove .toLowerCase() from the test
Please, stop it, your code is giving me cancer! There are a number of stylistic errors in the code that you need to fix.
First off in java, method names always begin with a lowercase letter. You are programming in Java, not C#, so you need to use the Java naming conventions. That means your method should be called search, not Search.
The same goes for variable names. What is BF supposed to mean, anyway? Replace it with in, please.
Next up, unless this method is in an object that itself represents that particular file, the global variable f should be passed as a parameter instead.
BufferedReader is AutoCloseable, so you should use a try-with-resources to deal with closing it.
You need to add a javadoc comment to it, documenting its parameters with #param, its return with #return, and exactly why it might need to throw an IOException with #exception.
Here is a mostly-fixed version of your code:
/**
* Needs Javadoc
*/
String search(String key, File f) throws IOException {
int lines = 0
String line = "";
String foundAt = "";
try(BufferedReader in = new BufferedReader(new FileReader(f)) {
while ((line = in.readLine().toLowerCase()) != null) { //the line in question
lines++;
StringTokenizer words = new StringTokenizer(line);
while(words.hasMoreTokens())
if (words.nextToken().equals(key.toLowerCase()))
foundAt = foundAt + "\n" + lines + ":" + line;
}
} catch(FileNotFoundException e){}
return foundAt;
}
Now, the problem here is that in.readline() returns a null sometimes. Calling a method on a null is always a NullPointerException. Therefore you get a NullPointerException when you attempt to call that null's missing toLowerCase() method.
You need to convert it toLowerCase after you ensure it is non-null.
I am reading an entire file and I want to use the line if it contains a specific string. I am unable to use the string because it is printing null outside the while loop, despite the fact that I have initialized it outside the loop.
FileInputStream wf = new FileInputStream(pr.getSplitDir() + listfiles[i]);
BufferedReader wbf = new BufferedReader(new InputStreamReader(wf));
String wfl = "";
while ((wfl = wbf.readLine()) != null) {
if (wfl.contains("A/C NO:")){
// System.out.println(wfl); // Here it is Printing the correct line
}
}
System.out.println(wfl); // Here it is printing null
Please help.
Try this below, You have to use another String or StringBuilder to get final out put
FileInputStream wf = new FileInputStream(pr.getSplitDir() + listfiles[i]);
BufferedReader wbf = new BufferedReader(new InputStreamReader(wf));
String wfl = "";
StringBuilder sb = new StringBuilder();
while ((wfl = wbf.readLine()) != null) {
if(wfl.contains("A/C NO:")){
//System.out.println(wfl);//Here it is Printing the correct line
sb.append(wfl);
}
}
System.out.println(sb.toString());//Here it is printing null
while ((wfl = wbf.readLine()) != null) {
if(wfl.contains("A/C NO:")){
//System.out.println(wfl);//Here it is Printing the correct line
}
}
Your while loop will exit only when wfl is null. So you have your answer!
To stop, your loop need wfl to be null, so when your loop has just stopped, wfl is obviously null.
Because your wbf.readLine when read null ,it assigns it wfl too and then compares to null
while ((wfl = wbf.readLine()) != null) { // here wbf.readLine when read null assigns to wfl
if(wfl.contains("A/C NO:")){
//System.out.println(wfl);//Here it is Printing the correct line
}
}
Do it like this,if you want to print outside while loop,
String test ="";
String wfl ="";
while ((wfl = wbf.readLine()) != null) {
if(wfl.contains("A/C NO:")){
//System.out.println(wfl);//Here it is Printing the correct line
}
test = test + wfl ; // for assigning all line
//test = wfl // for assigning last line
}
System.out.println(test); // it wil print the correct line
The code below is mostly self explanatory. However, I am having trouble in two cases:
The while loop does not exit even with the command line is left blank.
If the input is test t1 the key variable is supposed to be "test" (using System.out.println(key)) does that, but, it still doesn't enter the if condition for some reason.
String[] broken_text = null; String text = "";
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
while((text = reader.readLine()) != null) {
broken_text = text.split(" ");
String first_key = broken_text[0];
if (first_key == "test") {
//some statements
}
}
I am not sure why this is happening, any help regarding the same will be much appreciated.
use equals() to check string equality.
if (first_key == "test") {
//some statements
}
should be
if (first_key.equals("test")) {
//some statements
}
your text will never be null because you declared it as
String text = "";
thus your while loop would be an infinite loop
change
String text = "";
to
String text = null;
or if you wanna leave your text="" string as empty string.
use
while(!(text = reader.readLine()).isEmpty())
The loop does not end because a blank line causes readLine() to return an empty string, not null.
The comparison fails because Strings must be compared with equals() not ==
The String text will never be null in this case. You can use:
while (!(text = reader.readLine()).isEmpty()) {
this should be your edited code:
String[] broken_text = null;
String text = "";
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
while((text = reader.readLine()) != null && !text.isEmpty()) {
broken_text = text.split(" ");
String first_key = broken_text[0];
if ( "test".equals(first_key)) {
//some statements
}
}
The reason changed (text = reader.readLine()) != null to (text = reader.readLine()) != null && !text.isEmpty() is because readLine() returns null when it encounters end-of-file as the first character, and it returns "" (empty string) when the first character is encounters is \r (carriage return), \n(line feed) , or \r\n(carriage return followed by line feed). And you must always check for null before checking for isEmpty().
On unix / Linux console end-of-file is [ctrl][d] and on DOS it is [ctrl][z]
Note: In case you want to read input from a file (where you are more likely to get an end-of-file) instead of console, then your reader will be initialised like this:
BufferedReader reader = new BufferedReader(new FileReader("d:\\a1.txt"));
(assuming your input data is in file: "d:\a1.txt".)