Empty line in file - java

I could not find an explanation and those I found I am unsure of. So please confirm my doubts:
I am reading through a file using a while loop and if the line in the file is empty it skips and goes to next line. I just want to make sure the code I am using is correct for the what I just described:
while((strLine = reader.readLine())!= null) <----- While loop that is suppose to read Line by Line
{
if (strLine.isEmpty() == false) <----- Check for empty Line
{
/** My Code **/
}
else
{
/** My Code **/
}
}

Yes! What you are doing is what you want to do. You can just try compiling it yourself, you know. Trial and error. If you could not figure out how to use the reader, as the other answers propose, here you go:
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class Trial {
public static void main(String[] args) throws IOException {
String strLine;
BufferedReader reader = new BufferedReader(new FileReader(
"/home/user234/folder1/filename"));
while ((strLine = reader.readLine()) != null) {
if (!strLine.isEmpty()) {
System.out.println("notEMPTY");
} else {
System.out.println("EMPTY");
}
}
}
}

yes. it will work fine.
while(/* While scanner has next line */)
{
line = scanner.nextLine();
if( /* line is not equal to null */) {
/* perform code */
}
}

The logic shown in the above code makes sense to what you have described. It should perform what you desire.

The Java Reader does not have a readline() method.
If you want to do specific parsing of tokens you should use the Scanner. Scanner has a nextLine() method to grab each line, but throws an Exception if there is no next line. Therefore you should use Scanner.hasNextLine() for your while condition.
Scanner s = new Scanner("filename.txt");
String line;
while(s.hasNextLine()){ // check for next line
line = s.nextLine(); // get next line
if(line == ""){ // check if line is empty
System.out.println("Empty");
} else {
System.out.println("Not Empty:" + line);
}
}
Here's a live Example using Ideone.
EDIT: The BufferedReader does have a readline() method, as used by #natsirun. Although for any file parsing more complicated than line reading you would prefer the Scanner.

Related

Unexpected behavior constructing a java.util.Scanner

I have the following file lines.txt
Line1
Line2
Line3
I'm using a Scanner to parse the contents of this file line by line.
I have the following setup in LinesReader.java
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
class Line {
Line(String content) {
this.content = content;
}
public String content;
public String toString() {
return content;
}
}
public class LinesReader {
public static Line buildLine(InputStream is) {
Scanner scanner = new Scanner(is);
if (scanner.hasNextLine()) {
return new Line(scanner.nextLine());
}
return null;
}
public static Line buildLine(Scanner scanner) {
if (scanner.hasNextLine()) {
return new Line(scanner.nextLine());
}
return null;
}
public static void main(String[] args) throws FileNotFoundException {
List<Line> lines = new ArrayList<>();
Line line = null;
FileInputStream is = new FileInputStream("lines.txt");
// buildLine(scanner) works as expected
while ((line = buildLine(is)) != null) {
lines.add(line);
}
System.err.println(lines);
}
}
The output is
[Line1]
The expected output would be
[Line1, Line2, Line3]
I understand the Scanner implements AutoCloseable, but according to the documentation that would only apply for a
try-with-resources construct and not here. Also, when i debug it is says the underlying stream is open. The second call to scanner.hasNextLine() unexpectedly fails.
If I construct the scanner once in main() it works as expected.
My java version is 1.8.0_275
In response to a comment by #Sweeper the scanner seems to buffer up more than what is consumed, the documentation sort of contradicts that.
for hasNextLine()
The scanner does not advance past any input.
for nextLine()
Since this method continues to search through the input looking for a line separator, it may buffer all of the input searching for the line to skip if no line separators are present.
Emphasis mine.
The documentation for hasNextLine()
The scanner does not advance past any input.
is somewhat misleading. It doesn't advance the internal buffer of the scanner, which is obvious, but several kilobytes of the stream is read.
In this case the entire stream is consumed by hasNextLine().
My personal opinion is that this is a defect in the implementation of Scanner. Scanner is designed for convenience and simplicity, not for performance. Wrapping the InputStream in a BufferedInputStream would be sensible and make the usage a a lot simpler.
A Scanner is buffered, and one cannot expect that the underlying (File)InputStream is not read further than what is returned by nextLine. In fact the underlying FileInputStream could be advanced to the end-of-file. So the first Scanner instance could let the FileInputStream at the end-of-file.
Since java 8, it is easier to use Path, Files, Stream.
Path path = Paths.get("lines.txt");
try (Stream<String> in = Files.lines(path, Charset.defaultCharset())) {
List<Line> lines = in.map(Line::new)
.collect(Collectors.toList());
...
}
The above also automatically closes the file, try-with-resources syntax.
The code is smaller with the new classes.
Try this.
...
FileInputStream is = new FileInputStream("lines.txt");
while (true) {
System.err.println(is.available());
Scanner scanner = new Scanner(is);
if (scanner.hasNextLine()) {
lines.add(new Line(scanner.nextLine()));
} else {
break;
}
}
I got the following.
18
0 <---- FileInputStream is not avaliable for the 2nd Scanner
[Line1]
But if I move the line
while (true) {
FileInputStream is = new FileInputStream("lines.txt");
System.err.println(is.available());
...
}
the loop keeps printing out 18.

How to read characters in from a file from right to left

I am working on a program that evaluates lisp expressions using a stack implemented by either an array or linked list. I need to read the file in from the first line from right to left. Currently I am reading it in from left to right but I do not understand how I can switch it around. Any help you can give me is greatly appreciated! Thank you!
**I know the program is nowhere near complete, I just need to accomplish this before I can continue.
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.io.*;
import java.io.BufferedReader;
public class A2Q5{
private static Scanner in;
public static void main (String [] args)
{
if(args.length != 2) {
System.out.println("Please execute as: java A2Q5 type infile");
}
BoundedStack<Double> stack;
if(args[0].equals("0"))
stack = new BSArray<Double>(20);
else
stack = new BSLinkedList<Double>();
// The name of the file to open.
String fileName = args[1];
// This will reference one line at a time
//char c = null;
try {
BufferedReader br = new BufferedReader(new FileReader(fileName));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
for (int i = line.length() - 1; i >= 0; i--){
line.charAt(i);
System.out.println(line.charAt(i));
}
}
}
catch(FileNotFoundException ex) {
System.out.println("Unable to open file " + fileName);
}
catch(IOException ex) {
System.out.println("Error reading file " + fileName);
}
}
}
Drop the use of FileInputStream and use BufferedReader that you already prepared but never use. Use its method readLine to read info from your file line by line. Once you got an individual line you can iterate through it character by character from the end of the String to its beginning. This is exactly what you want.

Null in standard input in Java

I am working on small program where user inputs text in standard input and then this text is returned with proper alignment.
My main block of code where input is being read line by line:
public static void main(String[] args) {
try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
for (String nextLine, line = br.readLine(); line != null; line = nextLine) {
nextLine = br.readLine();
// Work with "line"
}
}
catch (IOException ex) {
System.exit(-1);
}
}
But input is never read all. Always last line is missing and line is never null. After little debugging I found out that br.readLine() on line nextLine = br.readLine(); doesn't return anything (literally it doesn't return anything. No exception is thrown though.) and program keeps running but is not executing any other lines of my code. I also tried reading from file and this problem doesn't occur.
That is probably because readLine() blocks until a new line is available or the stream reaches EOF (which never happens when you read from System.in).
You never get the last input because your loop always processes the previously read line.
Try this:
for (String line; (line = br.readLine()) != null;)
and break from this loop when you've read all the input you need, ex:
if(line.equals("finish")){
break;
}
When your input comes from standard input, you have to let your program know when the input ends. Otherwise it will keep waiting for the next input to be entered.
Therefore you should decide on some character or String that would mark the end of the input.
For example, here typing done would end the loop :
public static void main(String[] args) {
try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
for (String nextLine, line = br.readLine(); line != null && !line.equals("done"); line = nextLine) {
nextLine = br.readLine();
// Work with "line"
}
}
catch (IOException ex) {
System.exit(-1);
}
}

Terminate line without readLine() Method Java

As my Previous Question I used read() from java.io.FileInputStream and read(); provide output in same line without line terminated. After that I used readLine() from java.io.BufferedReader and got output in different line with line terminated. I explored readLine() method and I got this line from Java API Docs
Reads a line of text. A line is considered to be terminated by any one
of a line feed ('\n'), a carriage return ('\r'), or a carriage return
followed immediately by a linefeed.
After reading above quote from Java Docs, I modify my read(); method program to terminate line without readLine() method. But failed,
Here is the Modified code.(that I want to use for line terminated)
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class BoxDemo {
public static void main(String[] args) throws IOException {
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream("xanadu.txt");
out = new FileOutputStream("outagain.txt");
int c;
while ((c = in.read()) != -1) {
if((char)c=='\r' || (char)c=='\n') {
out.write('\n');
} else {
out.write(c);
}
}
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
}
Here is readLine(); method code that give output with line terminated.
import java.io.FileReader;
import java.io.FileWriter;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.io.IOException;
public class BoxDemo {
public static void main(String[] args) throws IOException {
BufferedReader inputStream = null;
PrintWriter outputStream = null;
try {
inputStream = new BufferedReader(new FileReader("xanadu.txt"));
outputStream = new PrintWriter(new FileWriter("characteroutput.txt"));
String l;
while ((l = inputStream.readLine()) != null) {
outputStream.println(l);
}
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
}
}
As reference, here's the output of your first code with the same xanadu.txt file as your last question:
Input:
In Xanadu did Kubla Khan
A stately pleasure-dome decree:
Where Alph, the sacred river, ran
Through caverns measureless to man
Down to a sunless sea.
Output:
In Xanadu did Kubla Khan
A stately pleasure-dome decree:
Where Alph, the sacred river, ran
Through caverns measureless to man
Down to a sunless sea.
So there's a redundant line break somewhere. This comes from the following if condition:
if((char)c=='\r' || (char)c=='\n') {
out.write('\n');
I'm guessing you are running this on a Windows machine where the line terminator is \r\n, so the characters \r and \n are actually both read, resulting in \n being written twice.
Again, since you seem to be using Windows, depending on your editor, it might not format \n as line breaks and outputs everything on a single line.
You can correct this by writing
out.write('\r');
out.write('\n');
explicitely.
With having said that, I do not recommend you to use this. You should use System.lineSeparator() where possible, as this results in the system dependant correct line separator.

Reading lines with BufferedReader and checking for end of file

If I have something like this in my code:
String line = r.readLine(); //Where r is a bufferedReader
How can I avoid a crash if the next line is the end of the file? (i.e. null)
I need to read the next line because there may be something there that I need to deal with but if there isn't the code just crashes.
If there is something there then all is OK, but I can't be guaranteed that there will be something there.
So if I do something like: (pseudo code):
if (r.readLine is null)
//End code
else {check line again and excecute code depending on what the next line is}
The issue I have with something like this is, that when I check the line against null, it already moves onto the next line, so how can I check it again?
I've not worked out a way to do this - any suggestions would be a great help.
Am... You can simply use such a construction:
String line;
while ((line = r.readLine()) != null) {
// do your stuff...
}
If you want loop through all lines use that:
while((line=br.readLine())!=null){
System.out.println(line);
}
br.close();
You can use the following to check for the end of file.
public bool isEOF(BufferedReader br)
{
boolean result;
try
{
result = br.ready();
}
catch (IOException e)
{
System.err.println(e);
}
return result;
}
In your case you can read the next line because there may be something there.If there isn't anything, your code won't crash.
String line = r.readLine();
while(line!=null){
System.out.println(line);
line = r.readLine();
}
A question in the first place, why don't you use "Functional Programming Approach"? Anyways, A new method lines() has been added since Java 1.8, it lets BufferedReader returns content as Stream. It gets all the lines from the file as a stream, then you can sort the string based on your logic and then collect the same in a list/set and write to the output file. If you use the same approach, there is no need to get worried about NullPointerException. Below is the code snippet for the same:-
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Collectors;
public class LineOperation {
public static void main(String[] args) throws IOException {
Files.newBufferedReader(Paths.get("C://xyz.txt")).
lines().
collect(Collectors.toSet()). // You can also use list or any other Collection
forEach(System.out::println);
}
}
You can do it via BufferReader. I know this is not relevant to following question. But I would post it for extra fact for a newbie who would not use BufferReader but Scanner for reading file.
A part from BufferReader you could use Java Scanner class to read the file and check the last line.
Buffer Reader
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String line;
while ((line = br.readLine()) != null) {
// process the line
}
}
Scanner
try {
Scanner scanner = new Scanner(new FileReader(file));
while (scanner.hasNext()) {
// Above checks whether it has or not ....
}
} catch (IOException e) {
e.printStackTrace();
}
If you use this code fragment in a multi threaded environment, go ahead with BufferReader since its synchronized.
In addition, BufferReader is faster than Scanner.
If you would like to do some check like:
if (reader.ready())
stringBuilder.append("#");
You can use ready()
public static void check() throws IOException {
InputStream in = new FileInputStream(new File(filePath));
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
if (reader.ready())
stringBuilder.append("#");
}
String returnedString = stringBuilder.toString();
System.out.println(returnedString);
}
You could purposely have it throw the error inside your loop. i.e.:
String s = "";
while (true) {
try {
s = r.readline();
}catch(NullPointerException e) {
r.close();
break;
}
//Do stuff with line
}
what everyone else has sad should also work.

Categories

Resources