Handling newline and empty strings with BufferedReader in Java - java

I am learning Java. I believe I have an issue understanding how BufferedReader processes "\n" or "" strings (newline and empty strings).
If I run the following it will fail if I put either of those strings into the String array.
String [] strings = {"55", "23", ""};
int total = 0;
for (String str : strings)
{
if (str != null) {
total += Integer.valueOf(str);
}
}
System.out.println(total);
This is fine, and makes sense to me. What does not make sense to me is when I run this code in reading in a file.
BufferedReader reader = null;
int total = 0;
try {
reader = new BufferedReader(new FileReader("E:\\Testing\\Numbers.txt"));
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
total += Integer.valueOf(line);
System.out.println("Total: " + total);
} catch(Exception e){
System.out.println(e.getMessage());
} finally {
try {
if (reader != null)
reader.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
using a text file that has the following:
5
2
3
It runs without errors. If I add a single blank line in the same file (), it fails with the message For input string: ""
I added an isNumeric function to solve the issue, but I don't understand why the BufferedReader will work when I run the code without any empty lines, even though it does not like the "\n" or "" strings. I looked up valueOf() in the javadocs and I did not see anything that helped me.
Here is my final code that uses the isNumeric function and shows how it sees both the "\n" and "" strings as non-numeric.
BufferedReader reader = null;
int total = 0;
try {
reader = new BufferedReader(new FileReader("E:\\Testing\\Numbers.txt"));
String line = null;
while ((line = reader.readLine()) != null) {
if (isNumeric(line))
{
System.out.println(line);
total += Integer.valueOf(line);
}
System.out.println("Skipping a non numeric value");
}
System.out.println("Total: " + total);
} catch(Exception e){
System.out.println(e.getMessage());
} finally {
try {
if (reader != null)
reader.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
public static boolean isNumeric(String str)
{
try
{
int d = Integer.parseInt(str);
}
catch(NumberFormatException nfe)
{
return false;
}
return true;
}
6
Skipping a non numeric value
1
Skipping a non numeric value
Skipping a non numeric value
2
Skipping a non numeric value
62
Skipping a non numeric value
23
Skipping a non numeric value
Total: 94
Finally I did see this article on the site, and it is close, but I still could not figure it out.

When using a BufferedReader, the readLine() method will consume any "new line like" characters automatically.
So, in essence, your initial file was
5\n
...
And the \n is simply removed before giving the string to your code. If the line is just \n; then you get "". An easy way to check for that is line.isEmpty().
Regarding: I don't understand why the BufferedReader will work when I run the code without any empty lines; well I don't understand that question. If your code only reads lines with numbers, it doesn't matter that you have code sitting there that could deal with empty lines; or lines containing "invalid" number text.

Related

Java NumberFormatException Error String to Float

Taking in a list of strings and converting them to a float and storing the values. I get this error when hitting the second value I want to store. Below is the code and the text file I'm reading from:
public static void readCities() {
StringBuilder sb = new StringBuilder();
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("C:/Users/Luke/workspace/Traveling Sales Person/Destinations/11PointDFSBFS.tsp"));
String line;
while ((line = br.readLine()) != null) {
if (sb.length() > 0) {
sb.append("\n");
}
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null) {
br.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
String contents = sb.toString();
String[] parts = contents.split("NODE_COORD_SECTION");//splits into locations
String[] locations = parts[1].split(" ");
int counter = 0;
for (int i = 1; i < locations.length; i++) {
cities[counter] = new City(Float.parseFloat(locations[i+1]), Float.parseFloat(locations[i+2]));
counter++;
}
}
Code error:
Exception in thread "main" java.lang.NumberFormatException: For input string: "63.860370
2
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)
at sun.misc.FloatingDecimal.parseFloat(FloatingDecimal.java:122)
at java.lang.Float.parseFloat(Float.java:451)
at TSP.readCities(TSP.java:132)
at TSP.main(TSP.java:28)
As all the commenters already said: Without the actual data it's more or less guessing, what is the problem, but with your code and the error-message some things can be said already, what you should do independly:
You read in all the lines and put them into a StringBuilder including a new line-break. Later on you do splits, but you never remove this line-break, so it is going to end up in the data you try to parse as float. This will lead to a parsing error, because spaces and other whitespaces are not removed. The easiest way to do this without changing too much in your code is by trimming the values:
cities[counter] = new City(Float.parseFloat(locations[i+1].trim()), Float.parseFloat(locations[i+2],trim()));
BTW: What's the reason for creating a new variable counter that is essentially i-1 and using i+1 and i+2 later on? Makes reading your code a bit harder, because you expect some additional logic where entries are skipped which isn't there.
According to the error-message the problem is a leading quotation mark and a newline. You can't say if that error occurred for the first or the second of the two values that are parsed and without the original line(s) of the input file it's hard to say, what is going on, but maybe I gave you enough hints to allow you to progress with your code.
If not we need more informations, especially the line(s) that produce this error, so analysing your code becomes possible.

Why does my method return 66

So I have this method here that should return the amount of lines in a csv file. Pretty simple right? Thing is instead of returning the amount of lines in the csv file(in this case 15) it returns 66. I honestly have know Idea why this would happen. I checked the csv file and verified that it is indeed 15 lines long with no empty lines. Also does anyone know why my Jpanes wont display without those three lines commented lines, my ide says the variables aren't in use anywhere.
public static int getLineCount(){
int line=0;
try {
Scanner inputStream = new Scanner(file);
while (inputStream.hasNext()) {
String data =inputStream.next();//this line is useless but the program doesn't display with out it
String[] values = data.split(",");//this line is useless but the program doesn't display with out it
i++;//this line is useless but the program doesn't display with out it
line++;
}
}catch(FileNotFoundException e){
e.printStackTrace();
}
return line;
}
Use BufferedReader instead of Scanner:
BufferedReader reader = new BufferedReader(new InputStreamReader(file));
while(reader.readLine() != null){
line++;
}
public static int getLineCount(){
String csvFilePath = "C:\\Users\\uzochi\\desktop\\txt.csv";
String line = "";
int numberOfLines=0;
try {
BufferedReader br = new BufferedReader(new FileReader(csvFilePath));
while (( line = br.readLine()) != null) {
numberOfLines++;
}
}catch(FileNotFoundException e){
//
}catch (IOException ex) {
//
}
return numberOfLines;
}

Line when reading a file is empty but the line is not null

I have a problem in java and i dont understand why, since i think i am doing text-book stuff.
An overview in what of want to do is:
I want to create a file that contains in each line two strings: documentPath, documentID (in this format: "documentPath;documentID;")
I want to be able to add lines at the end of the file and load the file to a Java Data Structure, lets say a HashSet.
Each time i want to add a new line, i load all the file in a HashSet, check if the line i want to add is not already there and eventually add it at the end. (small number of data - don't care about efficiency)
The code
Add file:
public void addFile(String documentPath) {
this.loadCollection(); //METHOD IS NOT CONTINUING: ERROR HERE
if (!documentsInfo.contains(documentPath)) {
try {
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(this.collectionFile, true)));
DocumentInfo documentInfo = new DocumentInfo(documentPath, ++this.IDcounter);
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Load file:
public void loadCollection() {
if (loaded) {return;}
BufferedReader br;
try {
br = new BufferedReader(new FileReader(collectionFile));
String line;
while ( (line = br.readLine())!= null ) { //PROBLEM HERE
System.out.println("the line readed from file-" + line + "-");
System.out.println("is the line null: "+ (line==null));
System.out.println("line length: " + line.length());
DocumentInfo documentInfo = new DocumentInfo(line);
documentsInfo.add(documentInfo);
}
br.close();
open = true;
} catch (IOException e) {
e.printStackTrace();
}
}
create the line to add:
public DocumentInfo(String fileLine) {
String delimiter = Repository.DOCUMENT_FILE_SEPARATOR;
StringTokenizer tok = new StringTokenizer(fileLine, delimiter);
System.out.println("Tokenizer starts with string: " + fileLine);
this.documentPath = tok.nextToken(); //EXCEPTION here
this.documentId = Integer.parseInt(tok.nextToken());
}
public String toString() {
String sep = Repository.DOCUMENT_FILE_SEPARATOR;
return this.getDocumentPath()+sep+this.getDocumentId()+sep+"\n";
}
I am getting the exception at the Tokenizer method (java.util.NoSuchElementException) when i try to get the nextToken, but the problem comes from the loadCollection() method. The first time i read the contents of the file nothing is there, the line is empty (lenght: 0) but the line is not null, so the while-condition fails to stop the while iteration.
Here is what i get from the debbuging prints:
the line readed from file--
is the line null: false
line length: 0
Tokenizer starts with string:
Can anyone help me with this?
You get a null only when you have exhausted the stream. But the first line of the stream (your file) is just an empty line - and you load it, the result of the empty line, is an empty string (""). It can be easily solved by skipping lines with string.length() == 0, by adding the following in your while loop:
if (line.length() == 0) continue;
You might want to consider using trim() before checking the length as well, to avoid nasty spaces making the string.length() > 0

Read, scan, modify a text file and put modified text into a new file

I've tried to read a text file and try to modify it. So many discussion that I got from StackOverflow, here is the content:
NO 1025 0
NO 1025 1
OP 1026 0
EndRow
The modified text file that I want:
NO 0
AND 1
OP 0
EndRow
I read some discussion topics about it, and then came the conclusion that I have to use the .hasNextLine method to check every line. Here's the code:
import java.io.*;
import java.util.Scanner;
public class MainConvert {
/**
* #nahdiya
*/
public static void main(String[] args) {
try {
File readNet = new File("testttt.net");
FileReader readFileNet = new FileReader(readNet);
BufferedReader reader = new BufferedReader(readFileNet);
Scanner scan = new Scanner("testttt.net");
PrintWriter fileConvert = new PrintWriter("convertNet.txt");
while (scan.hasNextLine()) {
String check = scan.next();
String checkLine = scan.nextLine();
if (checkLine.contains("NO 1025")) {
if(checkLine.contains("NO 1025")) {
fileConvert.println("AND "+check );
} else if (checkLine.contains("OP 1026")) {
fileConvert.println("OP"+check);
} else {
fileConvert.println(checkLine);}
}
}
}
reader.close();
fileConvert.close();
} catch(Exception ex) {
ex.printStackTrace();
}
}
When I tried to run the class, an output message appeared like this:
java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Unknown Source)
at fileConvertSave.MainConvert.main(MainConvert.java:21)
The problem is:
PrintWriter fileConvert = new PrintWriter("convertNet.txt");
What is the problem with this line? I just want to modify the testttt.net file. fileConvert must be created as the new file. What is wrong with it?
Edited: See the full solution at the bottom:
The original problem that was yielding the error message was the Scanner trying to perform nextLine() on a line that wasn't there due to:
String check = scan.next();
String checkLine = scan.nextLine();
When you call:
while( scan.hasNextLine() )
there is a next line available. You then call:
scan.next();
At this point there might not be a "next line" available anymore. You then call:
scan.nextLine()
and boom.
removing the line
String check = scan.next();
should work.
Edit:
Here is a solution to all the other parts of the problem... It's basically a complete rewrite of what you've got, so please read all the code, learn what it does and try to understand it all! If in doubt, please read the documentation first before asking a question.
BufferedReader reader = null;
PrintWriter writer = null;
try {
reader = new BufferedReader(new FileReader("testttt.txt"));
writer = new PrintWriter("convertNet.txt");
// setup the pattern that we want to find and replace in the input:
// NB> this is a regex (or regular expression)
// it means, find [space] then either 1025 or 1026 then [space]
String patternToMatch = " (1025|1026) ";
String inputLine = null;
// while there are lines to read, read them one at a time:
while ((inputLine = reader.readLine()) != null) {
// create the outputLine which is the input line with our pattern
// " 1025 " or " 1026 " replaced by just a single space:
String outputLine = inputLine.replaceFirst(patternToMatch, " ");
// log the transformation for debugging purposes:
System.out.println(inputLine + " -> " + outputLine);
// write the outputLine to the output file:
writer.println(outputLine);
}
}
catch (FileNotFoundException ex) {
System.out.println("file was not found: " + ex);
}
catch (IOException ex ) {
System.out.println("io error: " + ex);
}
finally {
try {
if( reader != null ) reader.close();
if ( writer != null ) writer.close();
} catch (IOException ex) {
System.out.println("error closing file " + ex);
}
}
Note that the finally block cleans up nicely even in the event there is an Exception. There's also a newer way to do this, that can make code a little shorter called try with resources:
http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
Your string does not look consistent i recommend you use regex if there are more strings like this and Bufferreader to read line, although i didn't use regex but this what i came up with,
public static void main(String[] args) {
try {
File readNet = new File("testttt.net");
FileReader readFileNet = new FileReader(readNet);
BufferedReader reader = new BufferedReader(readFileNet);
PrintWriter fileConvert = new PrintWriter("convertNet.txt");
String r = null;
while ((r = reader.readLine()) != null) {
System.out.println(r);
if (r.equals("NO 1025 1")) {
fileConvert.println(r.replace(r, "AND 1"));
} else if (r.contains("1025 0")) {
fileConvert.println(r.replaceAll("1025", ""));
} else if (r.contains("1026")) {
fileConvert.println(r.replaceAll("1026", ""));
} else {
fileConvert.println(r);
}
}
reader.close();
fileConvert.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
Good Luck, i hope it helps you.

Problems sending a message to a player

I have a problem with my bukkit plugin.
What I try to do is search through a file, and read it line by line (that works), then if the line has some text in it, it has to return that line, but it also has to return all the other lines in the file which also have that specific text in it. And when i have these lines, i have to send these lines in a message to the Player, that is not the problem, but when i send the lines i get now, the "\n" doesn't work, here is the code i use now:
public String searchText(String text, String file, Player p)
{
String data = null;
try {
BufferedReader br = new BufferedReader(new FileReader(file));
String line = null;
while((line = br.readLine()) != null)
{
if(line.indexOf(text) >= 0)
{
data += System.getProperty("line.separator") + line + System.getProperty("line.separator");
}
p.sendMessage("+++++++++++GriefLog+++++++++++");
p.sendMessage(data);
p.sendMessage("++++++++++GriefLogEnd+++++++++");
}
br.close();
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
The return is meant to be empty, because the info is returned to the player a bit higher:P
The problem now is, how do i add an "\n" to the data variable, because when i use this function in the rest of my code, it gives a lot of lines, but without the "\n", so how do i put that in?
Since your method isn't supposed to return anything, remove your return statement and set the return type to void.
It looks like your code would output the data string once for each line your search term occurs, try:
data = "";
while((line = br.readLine()) != null)
{
if(line.indexOf(text) >= 0)
{
//remove the first System.getProperty("line.separator") if
//you don't want a leading empty line
data += System.getProperty("line.separator") + line +
System.getProperty("line.separator");
}
}
if (data.length() > 0) {
p.sendMessage("+++++++++++GriefLog+++++++++++");
p.sendMessage(data);
p.sendMessage("++++++++++GriefLogEnd+++++++++");
}

Categories

Resources