How to read N amount of lines from a file? - java

I am trying to practice reading text from a file in java. I am little stuck on how I can read N amount of lines, say the first 10 lines in a file and then add the lines in an ArrayList.
Say for example, the file contains 1-100 numbers, like so;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- ....
I want to read the first 5 numbers, so 1,2,3,4,5 and add it to an array list. So far, this is what I have managed to do but I am stuck and have no clue what to do now.
ArrayList<Double> array = new ArrayList<Double>();
InputStream list = new BufferedInputStream(new FileInputStream("numbers.txt"));
for (double i = 0; i <= 5; ++i) {
// I know I need to add something here so the for loop read through
// the file but I have no idea how I can do this
array.add(i); // This is saying read 1 line and add it to arraylist,
// then read read second and so on
}

You could try using a Scanner and a counter:
ArrayList<Double> array = new ArrayList<Double>();
Scanner input = new Scanner(new File("numbers.txt"));
int counter = 0;
while(input.hasNextLine() && counter < 10)
{
array.add(Double.parseDouble(input.nextLine()));
counter++;
}
This should loop through 10 lines adding each to the arraylist as long as there is more inputs in the file.

See this How to read a large text file line by line using Java?
I think this will work:
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
int i = 0;
while ((line = br.readLine()) != null)
{
if (i < 5)
{
// process the line.
i++;
}
}
br.close();

ArrayList<String> array = new ArrayList<String>();
//ArrayList of String (because you will read strings)
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader("numbers.txt")); //to read the file
} catch (FileNotFoundException ex) { //file numbers.txt does not exists
System.err.println(ex.toString());
//here you should stop your program, or find another way to open some file
}
String line; //to store a read line
int N = 5; //max number of lines to read
int counter = 0; //current number of lines already read
try {
//read line by line with the readLine() method
while ((line = reader.readLine()) != null && counter < N) {
//check also the counter if it is smaller then desired amount of lines to read
array.add(line); //add the line to the ArrayList of strings
counter++; //update the counter of the read lines (increment by one)
}
//the while loop will exit if:
// there is no more line to read (i.e. line==null, i.e. N>#lines in the file)
// OR the desired amount of line was correctly read
reader.close(); //close the reader and related streams
} catch (IOException ex) { //if there is some input/output problem
System.err.println(ex.toString());
}

List<Integer> array = new ArrayList<>();
try (BufferedReader in = new BufferedReader(
new InputStreamReader(new FileInputStream("numbers.txt")))) {
for (int i = 0; i < 5; ++i) { // Loops 5 times
String line = in.readLine();
if (line == null) [ // End of file?
break;
}
// line does not contain line-ending.
int num = Integer.parseInt(line);
array.add(i);
}
} // Closes in.
System.out.println(array);

You can do this with:
try (BufferedReader reader = Files.newBufferedReader(Paths.get("numbers.txt"))) {
List<String> first10Numbers = reader.lines().limit(10).collect(Collectors.toList());
// do something with the list here
}
As complete example as JUnit test:
public class ReadFirstLinesOfFileTest {
#Test
public void shouldReadFirstTenNumbers() throws Exception {
Path p = Paths.get("numbers.txt");
Files.write(p, "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n".getBytes());
try (BufferedReader reader = Files.newBufferedReader(Paths.get("numbers.txt"))) {
List<String> first10Numbers = reader.lines().limit(10).collect(Collectors.toList());
List<String> expected = Arrays.asList("0", "1", "2", "3", "4", "5", "6", "7", "8", "9");
Assert.assertArrayEquals(expected.toArray(), first10Numbers.toArray());
}
}
}

ArrayList<Double> myList = new ArrayList<Double>();
int numberOfLinesToRead = 5;
File f = new File("number.txt");
Scanner fileScanner = new Scanner(f);
for(int i=0; i<numberOfLinesToRead; i++){
myList.add(fileScanner.nextDouble());
}
Make sure you have "numberOfLinesToRead" lines in your file.

BufferedReader br = new BufferedReader(new FileReader(file));
List<String> nlines = IntStream.range(0, hlines)
.mapToObj(i -> readLine(br)).collect(Collectors.toList());
String readLine(BufferedReader reader) {
try {
return reader.readLine();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}

Related

Need to read each N line from each file from List<Path>

I have List of Paths, each path represents file with text lines - i.e. 10 lines in each file.
My task is to read each first line from each file, then each second, each third and so on.
Trying to do this with BufferedReader so far results in it reading only first lines.
List<String> eachNLineFromEachFile = new ArrayList<>();
for (int i = 0; i < 10; i++) {
for (Path tempfile : tempFilesList) {
BufferedReader tempfileReader = Files.newBufferedReader(tempfile);
String line = null;
line = tempfileReader.readLine();
eachNLineFromEachFile.add(line);
try (BufferedWriter outputwriter = Files.newBufferedWriter(outputFile)) {
outputwriter.write(String.valueOf(eachNLineFromEachFile));
}
System.out.println(eachNLineFromEachFile);
}
}
So far it results with reading each first line of each file and then repeating with each first line.
How can get needed offset to work? I.e. each loop iteration to start reading from next line. AFAIK I should not use RandomAccessFile, which could probably do the trick with its getFilePointer and seek() methods).
Please help and thanks in advance.
You could add readers into an array / list and loop through as shown below or as suggested by one of the users - copy the content into a [][] or a map with key as line number and do whatever you want post that ...
List<String> eachNLineFromEachFile = new ArrayList<>();
//dummy for test.
List<Path> tempFilesList = new ArrayList<>();
List<BufferedReader> readers = new ArrayList<>();
for (Path tempfile : tempFilesList) {
BufferedReader tempfileReader = Files.newBufferedReader(tempfile);
readers.add(tempfileReader);
}
boolean read_complete = false;
while(true) {
for (BufferedReader reader : readers) {
String line = null;
try {
line = reader.readLine();
if(line == null) {
read_complete = true;
break;
}
eachNLineFromEachFile.add(line);
System.out.println(eachNLineFromEachFile);
} catch (IOException e) {
e.printStackTrace();
}
}
if(read_complete) {
break;
}
}
Reading your code I would expect the very same behavior as the one that you have described as problematic. You are just creating a new BufferedReader and a new BufferedWriter in each iteration, outputting a value. You would need instead to create an array of BufferedReader elements on the first iteration of the first cycle and repeat reading/writing the lines in the second cycle:
BufferedWriter bf = Files.newBufferedWriter(outputFile);
BufferedReader[] brs = new BufferedReader[10];
for (int i = 0; i < 10; i++) {
brs[i] = Files.newBufferedReader(tempFilesList.get(i));
}
for (int outerIndex = 0; outerIndex < 10; outerIndex++) {
for (int innerIndex = 0; innerIndex < 10; innerIndex++) {
String line = null;
line = brs[innerIndex].readLine();
bf.write(String.valueOf(line));
}
}

Cyclically call function based on segments of input

I'm working on a class assignment. I need to read in a file containing lines of input. Every block of three lines is a structured set: The first is one polynomial, the second is another polynomial, the third is a text string that indicates the algebraic operation for the polynomial arithmetic. I've set my program up so that it reads each line into an array, and then I parse the two array indices containing integers into my polynomial term. I call the appropriate function based on the third line. My struggle is finding a way to get the process to reset after each third line. Here is the code for my main function. I thought I would use an i-loop (k-loop here) somehow, but I can't get it to work. Any insight or suggestions greatly appreciated.
Example of input:
3 2 4 5
5 7 4 6
subtract
4 3 5 1
1 2 3 4
add
Here is my code:
public static void main(String[] args) throws IOException {
Polynomial p1 = new Polynomial();
Polynomial p2 = new Polynomial();
int lines = 0;
List<String> list = new ArrayList<String>();
try {
BufferedReader reader = new BufferedReader(new FileReader("Test.txt"));
String line=null;
while((line = reader.readLine()) != null) {
list.add(line);
lines++;
} // end while
} catch (FileNotFoundException e){
e.printStackTrace();
}
System.out.println("lines " + lines);
for (int k=0; k<lines; k++){
String[] stringArr = list.toArray(new String[0]);
System.out.println(stringArr[k+0]);
System.out.println(stringArr[k+1]);
System.out.println(stringArr[k+2]);
String[] nums1 = stringArr[k+0].split(" ");
String[] nums2 = stringArr[k+1].split(" ");
for (int i=0; i<nums1.length; i+= 2) {
p1.addTerm(Integer.parseInt(nums1[i]), Integer.parseInt(nums1[i+1]));
}
for (int i=0; i<nums2.length; i+= 2) {
p2.addTerm(Integer.parseInt(nums2[i]), Integer.parseInt(nums2[i+1]));
}
if (stringArr[k+2].equalsIgnoreCase("add")) {add(p1,p2);}
else if (stringArr[k+2].equalsIgnoreCase("subtract")) {subtract(p1,p2);}
else if(stringArr[k+2].equalsIgnoreCase("multiply")) {multiply(p1,p2);}
else {
System.out.println("Bad input");
}
nums1=null;
nums2=null;
}
}
Suggestion: Try something like the Scanner class? Catch the NoSuchElementException if it should run out of lines in the file.
Scanner scanner = new Scanner(new String("input"));
while(scanner.hasNextLine()) {
String lineOne = scanner.nextLine();
String lineTwo = scanner.nextLine();
String lineThree = scanner.nextLine();
calculateSomething(lineOne, lineTwo, lineThree);
}
It can be used to read strings to (space-delimited by default)
private static int[] getPolynomialFactors(String line) {
Scanner splitter = new Scanner(line);
int[] p = new int[4];
int counter=0;
while (splitter.hasNextInt()){
p[counter] = splitter.nextInt();
counter++;
}
return p;
}
With a good night's sleep, I was able to figure it out. I used a for-loop and just had to modify the incrementing of the loop counter. I nulled the pointers to the integer arrays I was using to store the integers parsed from the first two lines of the code block, which effectively reset them. Here is my updated code that works:
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
Polynomial p1 = new Polynomial();
Polynomial p2 = new Polynomial();
int lines = 0;
List<String> list = new ArrayList<String>();
try {
BufferedReader reader = new BufferedReader(new FileReader("Test.txt"));
String line=null;
while((line = reader.readLine()) != null) {
list.add(line);
lines++;
} // end while
} catch (FileNotFoundException e){
e.printStackTrace();
}
System.out.println("lines " + lines);
String[] stringArr = list.toArray(new String[0]);
for (int k=0; k<lines; k+=3){
System.out.println(stringArr[k+0]);
System.out.println(stringArr[k+1]);
System.out.println(stringArr[k+2]);
String[] nums1 = stringArr[k+0].split(" ");
String[] nums2 = stringArr[k+1].split(" ");
for (int i=0; i<nums1.length; i+= 2) {
p1.addTerm(Integer.parseInt(nums1[i]), Integer.parseInt(nums1[i+1]));
}
for (int i=0; i<nums2.length; i+= 2) {
p2.addTerm(Integer.parseInt(nums2[i]), Integer.parseInt(nums2[i+1]));
}
if (stringArr[k+2].equalsIgnoreCase("add")) {add(p1,p2);}
else if (stringArr[k+2].equalsIgnoreCase("subtract")) {subtract(p1,p2);}
else if(stringArr[k+2].equalsIgnoreCase("multiply")) {multiply(p1,p2);}
else {
System.out.println("Bad input");
break;
}
nums1=null;
nums2=null;
}
}
}

java read only integers from file

If I have a file that contains for example:
results1: 2, 4, 5, 6, 7, 8, 9
results2: 5, 3, 7, 2, 8, 5, 2
I want to add the integers from each line to a array. One array
for each line. How can I do this with code that does only read the integers?
Here's what I got this far
String data = null;
try {
Scanner in = new Scanner(new File(myFile));
while (in.hasNextLine()) {
data = in.nextLine();
numbers.add(data);
}
in.close();
} catch (Exception e) {
}
Easy.
One line per array, not two as you have it. New line after each one.
Read each line as a String, discard the leading "resultsX:", and split what remains at a delimiter of your choosing (e.g. comma). Parse each into an integer and add it to a List.
I don't think that leading "results1: " is adding any value. Why do you have that?
public static void main(String[] args) throws IOException {
BufferedReader reader=null;
try {
reader = new BufferedReader(new FileReader(new File("PATH TO FILE")));
// Only works if File allways contains at least two lines ... all lines after the second
// will be ignored
System.out.println(String.format("Array 1 : %s", Arrays.toString(stringArray2IntArray(readNextLine(reader)))));
System.out.println(String.format("Array 2 : %s", Arrays.toString(stringArray2IntArray(readNextLine(reader)))));
} finally {
if (reader!=null) {
reader.close();
}
}
}
private static Integer[] stringArray2IntArray(String[] numStrings) {
List<Integer> result = new ArrayList<Integer>();
for (int i = 0; i < numStrings.length; i++) {
result.add(Integer.parseInt(numStrings[i].trim()));
}
return result.toArray(new Integer[numStrings.length]);
}
private static String[] readNextLine(BufferedReader reader) throws IOException {
return reader.readLine().split(":")[1].split(",");
}
Assuming you have an input file, like this:
2,4,5,6,7,8,9
5,3,7,2,8,5,2
here is a code snippet to load it:
String firstLine = "";
String secondLine = "";
File file = new File("path/to/file");
try {
BufferedReader br = new BufferedReader(new FileReader(file));
firstLine = br.readLine();
secondLine = br.readLine();
} catch(Exception e){
e.printStackTrace();
}
String[] firstResult = firstLine.split(",");
String[] secondResult = secondLine.split(",");
int[] firstIntegers = new int[firstResult.length];
for(int i = 0; i <= firstResult.length ; i++){
firstIntegers[i] = Integer.parseInt(firstResult[i]);
}
int[] secondIntegers = new int[secondResult.length];
for(int i = 0; i <= secondResult.length ; i++){
firstIntegers[i] = Integer.parseInt(secondResult[i]);
}
Open the file with a BufferedReader br and then read it line by line.
Store each line in an int array and add all those int arrays to a list. At the end, this list will contain all the int arrays that we wanted, so iterate this list to do whatever you want to do next.
String filePath = "/path/to/file";
BufferedReader br = null;
List<Integer[]> arrays = new ArrayList<>(); //this contains all the arrays that you want
try {
br = new BufferedReader(new FileReader(filePath));
String line = null;
while ((line = br.readLine()) != null) {
line = line.substring(line.indexOf(":")+2); //this starts the line from the first number
String[] stringArray = line.split(", ");
Integer[] array = new Integer[stringArray.length];
for (int i = 0; i < stringArray.length; ++i) {
array[i] = Integer.parseInt(stringArray[i]);
}
arrays.add(array);
}
} catch (FileNotFoundException ex) {
System.err.println(ex);
} catch (IOException ex) {
System.err.println(ex);
} finally {
try {
br.close();
} catch (Exception ex) {
System.err.println(ex);
}
}
Since ArrayLists keep insertion order, then, e.g., arrays.get(3) will give you the array of the fourth line (if there is such a line) and arrays.size() will give you the number of lines (i.e., int arrays) that are stored.

In Java how to check if the next record in a file is the end?

I want to sequentially read each line of an input unsorted file into consecutive elements of the array until there are no more records in
the file or until the input size is reached, whichever occurs first. but i can't think of a way to check the next line if its the end of the file?
This is my code:
Scanner cin = new Scanner(System.in);
System.out.print("Max number of items: ");
int max = cin.nextInt();
String[] input = new String[max];
try {
BufferedReader br = new BufferedReader(new FileReader("src/ioc.txt"));
for(int i=0; i<max; i++){ //to do:check for empty record
input[i] = br.readLine();
}
}
catch (IOException e){
System.out.print(e.getMessage());
}
for(int i=0; i<input.length; i++){
System.out.println((i+1)+" "+input[i]);
}
the file has 205 lines, if I input 210 as max, the array prints with five null elements like so..
..204 Seychelles
205 Algeria
206 null
207 null
208 null
209 null
210 null
Thanks for your responses in advance!
From the docs:
public String readLine()
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
In other words, you should do
String aux = br.readLine();
if(aux == null)
break;
input.add(aux)
I recomend you use a variable-size array (you can pre-allocated with the requested size if reasonable). Such that you get either the expected size or the actual number of lines, and can check later.
(depending on how long your file is, you might want to look at readAllLines() too.)
Please refer this Number of lines in a file in Java and modify your for loop to take whatever is the least out of the entered max value or the no.of lines in the file.
Use List<String>
List<String> lines = new ArrayList<>(); // Growing array.
try (BufferedReader br = new BufferedReader(new FileReader("src/ioc.txt"))) {
for(;;) {
String line = br.readLine();
if (line == null) {
break;
}
lines.add(line);
}
} catch (IOException e) {
System.out.print(e.getMessage());
} // Closes automatically.
// If lines wanted as array:
String[] input = lines.toArray(new String[lines.size()]);
Using a dynamically growing ArrayList is the normal way to deal with such problem.
P.S.
FileReader will read in the current platform encoding, i.e. a local file, created locally.
You could do a null check in your first for-loop like:
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
System.out.print("Max number of items: ");
int max = cin.nextInt();
BufferedReader br = new BufferedReader(new FileReader("src/ioc.txt"));
List<String> input = new ArrayList<>();
String nextString;
int i;
for (i = 0; i < max && ((nextString = br.readline()) != null); i++) {
input.add(nextString);
}
for (int j = 0; j < i; j++) {
System.out.println((j + 1) + " " + input.get(j));
}
}
Try :
for(int i=0; i<max; i++){ //to do:check for empty record
if(br.readLine()!=null)
input[i] = br.readLine();
else
break;
}
int i=0;
for(; i<max; i++){ //to do:check for empty record
String line=br.readLine();
if(line==null){
break;
}
input[i] = line;
}
//i will contain the count of lines read. indexes 0...(i-1) represent the data.

How to assign a text file's lines of integers into 2D tables in Java?

I have the sample.txt which contains 100 Integers (range 0-9) in every line formatted like this:
9 2 0 3 4 1 0 7 5 3 7 8 6 2 0 1 4 4 5 9 0 3 2 1 7 (etc... 100 numbers)
I want to scan the file and put every line into a 10x10 table. So:
public void loadTableFromFile(String filepath){
try (Scanner s = new Scanner(new BufferedReader(new FileReader(filepath)))) {
String line;
while (s.hasNextLine()) {
// WHAT HERE? THIS BLOCK DOES NOT WORK
/* if (s.hasNextInt()) {
//take int and put it in the table in the right position procedure
} else {
s.next();
} */
// END OF NOT WORKING BLOCK
}
} catch (FileNotFoundException e){
}
}
How about something like this?
public void loadTableFromFile(String filepath) {
Scanner s = null; // Our scanner.
try {
s = new Scanner(new BufferedReader(
new FileReader(filepath))); // get it from the file.
String line;
while (s.hasNextLine()) { // while we have lines.
line = s.nextLine(); // get a line.
StringTokenizer st = new StringTokenizer(line, " ");
int i = 0;
while (st.hasMoreTokens()) {
if (i != 0) {
System.out.print(' '); // add a space between elements.
}
System.out.print(st.nextToken().trim()); // print the next element.
i++;
if (i % 10 == 0) { // Add a new line every ten elements.
System.out.println();
}
}
System.out.println(); // between lines.
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (s != null)
s.close();
}
}
Here is a solution that reads the line of the file into an array of strings using the split by whitespace method, and then reads them in using a for loop. I threw any exceptions that might have occurred in the method declaration, alternatively, use the try catch loop as above (might be better design, not sure about that.)
public void loadTableFromFile(String filePath) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(filePath));
String[] line = br.readLine().split(" ");
br.close(); // file only has 1 line with 100 integers
int[][] mydata = new int[10][10];
for(int i = 0; i < line.length; i++) {
mydata[i % 10][(int) (i / 10)] = Integer.parseInt(line[i]);
}
}
Now, if the file has more than one line, you could instead read the entire file line by line, and then use the above idea like this:
BufferedReader br = new BufferedReader(new FileReader(filePath));
String line1;
while((line1 = br.readLine()) != null) {
String[] line = line1.split(" ");
... // do above stuff of reading in 1 line here
}
br.close();
Try,
try (Scanner s = new Scanner(new BufferedReader(new FileReader(filepath)))) {
String line;
while (s.hasNextLine()) {
String[] strArr=line.split(" ");
for(int i=0;i<strArr.length;i++){
System.out.print(" "+strArr[i]);
if((i+1)%10==0){
System.out.println();
}
}
}
} catch (FileNotFoundException e){
}

Categories