I am taking data from a text file and putting it into an ArrayList. However the first line of the text file is not being printed out.
public static void secondMain() {
BufferedReader reader;
var lines = new ArrayList<String>();
var rooms = new ArrayList<Room>();
try {
reader = new BufferedReader(new FileReader("rooms.txt"));
String line = reader.readLine();
while (line != null) {
line = reader.readLine();
lines.add(line);
}
reader.close();
for (int i = 0; i < lines.size() - 1; i++) {
String[] words = lines.get(i).split(" ");
var room = new Room();
room.RoomNumber = Integer.parseInt(words[0]);
room.Type = (words[1]);
room.Price = Double.parseDouble(words[2]);
room.Bool1 = Boolean.parseBoolean(words[3]);
room.Bool2 = Boolean.parseBoolean(words[4]);
room.Availability = (words[5]);
rooms.add(room);
}
for(int i = 0; i < rooms.size(); i++) {
System.out.println(rooms.get(i).RoomNumber);
System.out.println(rooms.get(i).Type);
System.out.println(rooms.get(i).Price);
System.out.println(rooms.get(i).Bool1);
System.out.println(rooms.get(i).Bool2);
System.out.println(rooms.get(i).Availability);
}
Apologies for the Image, it was the only way i could figure out how to show the formatting of the text file.
The current output is displaying room number 102 as the first room which obviously isn't correct.
If anyone could also help me figure out how to format my console output the same way as the text file that'd also be great. currently it is displaying each individual string/int etc. on a different line.
Thanks.
If you need any more information please just ask!
This has nothing to do with the ArrayList. You can reproduce the problem by replacing the lines.add(line) call with System.out.println(line) and you'll see that the first line is missing from the output. Look at your first call to readLine(), before the while loop. You test that the value is non-null... and that's all you do with it (comments mine):
String line = reader.readLine(); // Read the value...
while (line != null) { // Test for it being non-null
line = reader.readLine(); // Then ignore the value you've just tested,
// by reading the next line.
lines.add(line);
}
You then call readLine() again. Note that your list will always end with a null value (unless it's the first line read) because your loop effectively says "while the last entry I added to the list isn't null". The simplest fix is to swap the order of the statements within your loop:
String line = reader.readLine();
while (line != null) {
lines.add(line);
line = reader.readLine();
}
Now you're adding a line immediately after checking whether it's non-null, before reading the next line.
The problem is here:
String line = reader.readLine(); // you read the first line
while (line != null) {
line = reader.readLine(); // read second line
lines.add(line); // add second line
}
You read the first line, check if it's not null, and then read the second line right away, before you add it to the list. All you need to do is switch the order.
String line = reader.readLine();
while (line != null) {
lines.add(line);
line = reader.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 am trying to iterate through a CSV file in Java. It iterates through the entire file, but will get to the end of the file and try to read the next blank line and throw an error. My code is below.
public class Loop() {
public static void main(String[] args) {
BufferedReader br = null;
String line = "";
try {
HashMap<Integer, Integer> changeData = new HashMap<Integer, Integer>();
br = new BufferedReader(new FileReader("C:\\xxxxx\\xxxxx\\xxxxx\\the_file.csv"));
String headerLine = br.readLine();
while ((line = br.readLine()) != null) {
String[] data = line.split(",");
/*Below is my latest attempt at fixing this,*/
/*but I've tried other things too.*/
if (data[0].equals("")) { break; }
System.out.println(data[0] + " - " + data[6]);
int changeId = Integer.parseInt(data[0]);
int changeCv = Integer.parseInt(data[6]);
changeData.put(changeId, changeCv);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Like I typed, this works fine until it gets to the end of the file. When it gets to the end of the file, I get the error Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0 at com.ucg.layout.ShelfTableUpdates.main(ShelfTableUpdates.java:23). I've stepped through the code by debugging it in Spring Tool Suite. The error comes up whenever I try to reference data[0] or data[6]; likely because there is nothing in that line. Which leads me back to my original question of why it is even trying to read the line in the first place.
It was my understanding that while ((line = br.readLine()) != null) would detect the end of the file, but it doesn't seem to be. I've tried re-opening the file and deleting all of the blank rows, but that did not work.
Any idea how I can detect the end of the file so I don't get an error in this code?
ANSWER:
Credit goes to user #quemeraisc. I also was able to replace the commas with blanks, and if the line then equals null or "", then you know that it is the end of the file; in my case, there are no blank rows before the end of the file. This still does not solve the problem of detecting the end of the file in that if I did have blank rows in between my data that were not the EOF then this would detect those.
Solution 1:
if (data.length < 7) {
System.out.println(data.length);
break;
}
Solution 1:
if (line.replace(",", "").equals(null) || line.replace(",", "").equals("")) {
System.out.println(line.replace(",", ""));
break;
}
Just skip all blank lines:
while ((line = br.readLine()) != null) {
if( line.trim().isEmpty() ) {
continue;
}
....
....
The last line may contain some control characters (like new line, carriage return, EOF and others unvisible chars), in this case a simple String#trim() doesn't remove them, see this answer to know how to remove them: How can i remove all control characters from a java string?
public String readLine() will read a line from your file, even empty lines. Thus, when you split your line, as in String[] data = line.split(","); you get an array of size 1.
Why not try :
if (data.length >= 7)
{
System.out.println(data[0] + " - " + data[6]);
int changeId = Integer.parseInt(data[0]);
int changeCv = Integer.parseInt(data[6]);
changeData.put(changeId, changeCv);
}
which will make sure there are at least 7 elements in your array before proceeding.
To skip blank lines you could try:
while ((line = reader.readLine()) != null) {
if(line.length() > 0) {
String[] data = line.split(",");
/*Below is my latest attempt at fixing this,*/
/*but I've tried other things too.*/
if (data[0] == null || data[0].equals("")) { break; }
System.out.println(data[0] + " - " + data[6]);
int changeId = Integer.parseInt(data[0]);
int changeCv = Integer.parseInt(data[6]);
changeData.put(changeId, changeCv);
}
}
Instead of replace method use replaceAll method. Then it will work.
so i have an input txt file where i have to take the first 50 lines and reverse it's order so that the file will start with the 50th line, then the 49th, until the 1st, then continues with the 100th line followed by the 99th, and so on...
but i can only store at most 50 elements. i can't store more than that.
the code i've written so far only grabs the first 50 lines and reverses them, but i dont know how to make it continue on.
this is what i have so far:
ArrayList<String> al = new ArrayList<String>();
int running = 0;
while(running == 0) {
for (String line = r.readLine(); line != null; line = r.readLine()) {
if(al.size() <50 ) {
al.add(line);
}
}
Collections.reverse(al);
for (String text : al) {
w.println(text);
}
if(al.size() < 50) {
break;
}
al.clear();
}
idk why my while loop won't keep running, im only getting the first 50 lines reversed in my output file.
This:
for (String line = r.readLine(); line != null; line = r.readLine()) {
if(al.size() <50 ) {
al.add(line);
}
}
reads all the lines in the file, stores the first fifty in al, and discards the rest. After you then process the results of al, there's nothing more for your program to do: it's read the whole file.
There's a great blog post on how to debug small programs, that I highly recommend: http://ericlippert.com/2014/03/05/how-to-debug-small-programs/
And in your specific case, I suggest breaking your program into functions. One of those functions will be "read up to n lines, and return them in an array-list". This sort of structure makes it easier to reason about each part of the program.
Your initial loop:
for (String line = r.readLine(); line != null; line = r.readLine()) {
if(al.size() <50 ) {
al.add(line);
}
}
Continues to read lines after you've filled al through to the end of the file - it just doesn't put them in the list.
You most likely need something like:
for (String line = r.readLine(); line != null; line = r.readLine()) {
if (al.size() == 50)
outputReverseLines();
al.add(line);
}
outputReverseLines();
Where outputReverseLines is a method that reverses, prints and clears the list.
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));
}
}
How can i read single line from a text file in java.
and what is the criteria of knowing that line is completed.
secondly
i read file and then for Read Line function and converting it into string will skip a lot of data? what should be the problem?
Here is my code
String data = new String();
while(infile.readLine() != null) {
data = infile.readLine();
System.out.println(data);
}
Change your code as follows
while((data = infile.readLine()) != null) { // read and store only line
System.out.println(data);
}
In your current code
while(infile.readLine() != null) { // here you are reading one and only line
data = infile.readLine(); // there is no more line to read
System.out.println(data);
}
You are reading an extra line because the first readLine() as the while condition reads a line but it is used at all. The second readLine() inside the while loop read the second line which you're assigning to data and printing.
Therefore you need to assign the line read in the while condition to data and print it, as that is the first line.
while((data = infile.readLine()) != null) { // reads the first line
// data = infile.readLine(); // Not needed, as it reads the second line
System.out.println(data); // print the first line
}
Also, since you just need to read the first line, you don't need the while at all. A simple if would do.
if((data = infile.readLine()) != null) { // reads the first line
System.out.println(data); // print the first line
}
With the BufferedReader and the code you posted in the comments, your main should now look like this.
public static void main(String[] args) {
try {
FileInputStream fstream = new FileInputStream(args[0]);
BufferedReader infile = new BufferedReader(new InputStreamReader(
fstream));
String data = new String();
while ((data = infile.readLine()) != null) { // use if for reading just 1 line
System.out.println(data);
}
} catch (IOException e) {
// Error
}
}
First thing : readLine() returns String value only so it is not converting to String.
Second thing : In your while loop, you read firstline and check whether the content of first line is null or not. But when data = infile.readLine(); executes, it will fetch second line from file and print it to Console.
Change your while loop to this :
while((data = infile.readLine()) != null){
System.out.println(data);
}
If you use toString() method, it will throw NPE when it will try to use toString method with null content read from infile.