Java - splitting files by newline - java

How can I split file by newline? I've attempted to split by doing line.split("\\r?\\n") - but when I try printing the 0th index I get the entire file content when I was expecting just the first line. but if I try printing the result at index 0 I get the entire file content, when I expected to get just the first line.
FileInputStream file = new FileInputStream("file.rcp");
BufferedReader reader = new BufferedReader(new InputStreamReader(file));
String line = reader.readLine();
while (line != null) {
String [] split = line.split("\\r?\\n");
String name = split[0]; // test to see if name will print the first line only
System.out.println(name);
line = reader.readLine();
}
File format
Food name - gyros
author - some name
Cusine type - greek
Directions - some directions
Ingredients - some ingredients

The documentation, i.e. the javadoc of readline(), says:
Returns a String containing the contents of the line, not including any line-termination characters
Which means that line.split("\\r?\\n") is the same as new String[] { line }, i.e. it's an entirely useless thing to do.
If you want to read the entire file into memory as an array of lines, just call Files.readAllLines():
List<String> linesList = Files.readAllLines(Paths.get("file.rcp"));
String[] linesArray = linesList.toArray(new String[0]);

You do not need to split any string at all. You can simply read a line and add it to a List<String> (or an array if the number of lines is known).
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) throws IOException {
FileInputStream file = new FileInputStream("file.rcp");
List<String> list = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(file))) {
String line = reader.readLine();
while (line != null) {
list.add(line);
line = reader.readLine();
}
}
System.out.println(list);
// An array out of the list
String[] arr = list.toArray(new String[0]);
System.out.println(Arrays.toString(arr));
}
}
Output:
[Food name - gyros, author - some name, Cusine type - greek, Directions - some directions, Ingredients - some ingredients]
[Food name - gyros, author - some name, Cusine type - greek, Directions - some directions, Ingredients - some ingredients]
If you have already read the content of your file into some string (e.g. String fileContent as shown below), you can simply split the string on \r?\n which will produce a String[].
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
public class Main {
public static void main(String[] args) throws IOException {
String fileContent = new String(Files.readAllBytes(Paths.get("file.rcp")));
// Java11 onwards
// String fileContent = Files.readString(Path.of("file.rcp"));
String[] arr = fileContent.split("\\r?\\n");
System.out.println(Arrays.toString(arr));
}
}
Output:
[Food name - gyros, author - some name, Cusine type - greek, Directions - some directions, Ingredients - some ingredients]

Related

Convert a .txt file with doubles to an ArrayList

I have a .txt file with this content: "17.23;12.1;20.34;88.23523;".
I want to read this file as doubles into an ArrayList. And eventually print the ArrayList (and eventually print the min. and max., but I don't think that will be a problem after solving this).
But I only get the output "[ ]".
What am I doing wrong? I've been struggling with this for embarrassing 15+ hours, browsed here, youtube, course books...
My code:
public static void main(String[] args) throws IOException {
File myFile = new File("text.txt");
Scanner scan = new Scanner(myFile);
ArrayList<Double> aList = new ArrayList<>();
while (scan.hasNextDouble()) {
double nextInput = scan.nextDouble();
if (nextInput != 0) {
break;
}
aList.add(nextInput);
}
System.out.println(alist);
}
You should configure your scanner so it will accept:
; as a delimiter
, as a decimal separator
Working code is:
File myFile = new File("input.txt");
// Swedish locale uses ',' as a decimal separator
Scanner scan = new Scanner(myFile).useDelimiter(";").useLocale(Locale.forLanguageTag("sv-SE"));
ArrayList<Double> aList = new ArrayList<>();
while (scan.hasNextDouble()) {
double nextInput = scan.nextDouble();
aList.add(nextInput);
}
System.out.println(aList);
With output [17.23, 12.1, 20.34, 88.23523]
Scanner works by splitting the input into tokens, where tokens are separated by whitespaces (by default). Since there are no whitespaces in the text, the first/only token is the entire text, and since that text is not a valid double value, hasNextDouble() returns false.
Two ways to fix that:
Change the token separator to ;:
scan.useDelimiter(";");
Read the file with BufferedReader and use split():
String filename = "text.txt";
try (BufferedReader in = Files.newBufferedReader(Paths.get(filename))) {
for (String line; (line = in.readLine()) != null; ) {
String[] tokens = line.split(";");
// code here
}
}
That will now result in the following tokens: 17,23, 12,1, 20,34, 88,23523.
Unfortunately, none of those are valid double values, because they use locale-specific formatting, i.e. the decimal point is a ,, not a ..
Which means that if you kept using Scanner, you can't use hasNextDouble() and nextDouble(), and if you changed to use split(), you can't use Double.parseDouble().
You need to use a NumberFormat to parse locale-specific number formats. Since "Uppgift" looks Swedish, we can use NumberFormat.getInstance(Locale.forLanguageTag("sv-SE")), or simply NumberFormat.getInstance() if your default locale is Sweden.
String filename = "text.txt";
try (BufferedReader in = Files.newBufferedReader(Paths.get(filename))) {
NumberFormat format = NumberFormat.getInstance(Locale.forLanguageTag("sv-SE"));
for (String line; (line = in.readLine()) != null; ) {
List<Double> aList = new ArrayList<>();
for (String token : line.split(";")) {
double value = format.parse(token).doubleValue();
aList.add(value);
}
System.out.println(aList); // Prints: [17.23, 12.1, 20.34, 88.23523]
}
}
You can do it simply by changing the delimiter. This works by reading from a String but you can also do it from a file. It is up to you to put the values in some data structure. This presumes your default locale uses ',' as a decimal point.
String str = "17,23;12,1;20,34;88,23523;";
Scanner scan = new Scanner(str);
scan.useDelimiter("[;]+");
while(scan.hasNextDouble()) {
System.out.println(scan.nextDouble());
}
prints
17.23
12.1
20.34
88.23523
Since your file has numbers separated by a semi-colon, you won't be able to read them using scan.hasNextDouble() by default. However, there are so many ways of doing it e.g.
Override the default delimiter.
Reading a line as string and process each number from it after splitting it on the semi-colon.
Option-1:
scan.useDelimiter(";")
Note that since your file has the comma instead of the dot as the decimal symbol, you can use a Locale in which it is the default.
scan.useLocale(Locale.FRANCE);
Also, the following code block in your code will cause the loop to be terminated after reading the first number itself as the first number in your file in not equal to zero. Simply remove these lines in order to get the desired result:
if (nextInput != 0) {
break;
}
Option-2:
Read a line, split it on a semi-colon, replace the comma with a dot, parse each element from the resulting array into Double and store the same into aList.
Demo:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws FileNotFoundException {
File myFile = new File("file.txt");
Scanner scan = new Scanner(myFile);
List<Double> aList = new ArrayList<>();
while (scan.hasNextLine()) {
String nextInput = scan.nextLine();
String[] arr = nextInput.split(";");
for (String s : arr) {
aList.add(Double.valueOf(s.replace(",", ".")));
}
}
System.out.println(aList);
}
}
Output:
[17.23, 12.1, 20.34, 88.23523]
An alternative to replace comma with dot is to use NumberFormat as shown below:
import java.io.File;
import java.io.FileNotFoundException;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws FileNotFoundException, ParseException {
File myFile = new File("file.txt");
Scanner scan = new Scanner(myFile);
NumberFormat format = NumberFormat.getInstance(Locale.FRANCE);
List<Double> aList = new ArrayList<>();
while (scan.hasNextLine()) {
String nextInput = scan.nextLine();
String[] arr = nextInput.split(";");
for (String s : arr) {
aList.add(format.parse(s).doubleValue());
}
}
System.out.println(aList);
}
}

Read a line and push into a line-stack until the end of file

I have to do a program and unfortunately I have no idea where to start. It's like we were doing very basic coding and then my teacher went on maternity leave and our substitute thinks we are further along then we actually are. I know how to ready from a file, but I do not know how to put the line into a stack from there.
These are the instructions
1) Read a line and push into a line-stack until the end of file 2) While line_stack is not empty a. Pop one element out and process the following i. Split elements in this line (i.e. numbers) using StringTokenzier ii. Push all numbers into number-stack iii. While number_stack is not empty 1. Pop a number 2. Print a character using that ascii number
If I understand the problem correctly you need to:
Represent a line as a java.lang.String.
Then using java.util.Stack create a Stack< String> and put all the lines there.
Use java.util.StringTokenizer to split each line into multiple parts. Each part will be a String itself.
Turn each part of the line into a number using Integer.valueOf(String)
Put all the numbers into a Stack< Integer>.
Print the right character for each number by casting integer value to char.
I think this may be the solution for your problem:
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Stack;
import java.util.StringTokenizer;
public class LinesProcessor {
private static Stack<String> readLinesFromFile(String fileName) throws IOException {
Stack<String> lines = new Stack<>();
try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(fileName)))) {
String line = null;
while ((line = br.readLine()) != null) {
lines.push(line);
}
}
return lines;
}
private static void processNumbers(Stack<Integer> stackOfNumbers) {
while (!stackOfNumbers.empty()) {
Integer number = stackOfNumbers.pop();
System.out.print((char) number.intValue());
}
}
private static void processLine(String line) {
StringTokenizer tokenizer = new StringTokenizer(line, " ");
Stack<Integer> stackOfNumbers = new Stack<>();
while (tokenizer.hasMoreTokens()) {
Integer number = Integer.valueOf(tokenizer.nextToken());
stackOfNumbers.push(number);
}
processNumbers(stackOfNumbers);
}
private static void processLines(Stack<String> stackOfLines) {
while (!stackOfLines.empty()) {
String currentLine = stackOfLines.pop();
processLine(currentLine);
}
}
public static void main(String[] args) throws IOException {
if (args.length < 1) {
System.out.println("Name of file missing");
System.exit(1);
}
String fileName = args[0];
Stack<String> stackOfLines = readLinesFromFile(fileName);
processLines(stackOfLines);
}
}

Adding data from .txt document to array

Below is what the text document looks like. The first line is the number of elements that I want the array to contain. The second is the ID for the product, separated by # and the third line is the total price of the products once again separated by #
10
PA/1234#PV/5732#Au/9271#DT/9489#HY/7195#ZR/7413#bT/4674#LR/4992#Xk/8536#kD/9767#
153#25#172#95#235#159#725#629#112#559#
I want to use the following method to pass inputFile to the readProductDataFile method:
public static Product[] readProductDataFile(File inputFile){
// Code here
}
I want to create an array of size 10, or maybe an arrayList. Preferably to be a concatenation of Customer ID and the price, such as Array[1] = PA/1234_153
There you go the full class, does exactly what you want:
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.Arrays;
import java.io.FileNotFoundException;
import java.io.IOException;
class myRead{
public static void main(String[] args) throws FileNotFoundException, IOException {
BufferedReader inputFile = new BufferedReader(new FileReader("test.txt"));
String numberOfElements = inputFile.readLine();
//this is the first line which contains the number "10"
//System.out.println(numberOfElements);
String secondLine = inputFile.readLine();
//this is the second line which contains your data, split it using "#" as a delimiter
String[] strArray = secondLine.split("#");
//System.out.println(Arrays.toString(strArray));
//System.out.println(strArray[0]);
String thirdLine = inputFile.readLine();
//this is the third line which contains your data, split it using "#" as a delimiter
String[] dataArray = thirdLine.split("#");
//combine arrays
String[] combinedArray = new String[strArray.length];
for (int i=0;i<strArray.length;i++) {
combinedArray[i]=strArray[i]+"_"+dataArray[i];
System.out.println(combinedArray[i]);
}
}
}
OUTPUT:
PA/1234_153
PV/5732_25
Au/9271_172
DT/9489_95
HY/7195_235
ZR/7413_159
bT/4674_725
LR/4992_629
Xk/8536_112
kD/9767_559
The trick in what I am doing is using a BufferedReader to read the file, readLine to read each of the three lines, split("#"); to split each token using the # as the delimiter and create the arrays, and combinedArray[i]=strArray[i]+"_"+dataArray[i]; to put the elements in a combined array as you want...!
public static Product[] readProductDataFile(File inputFile){
BufferedReader inputFile = new BufferedReader(new FileReader(inputFile));
// the rest of my previous code goes here
EDIT: Everything together with calling a separate method from inside the main, with the file as an input argument!
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.Arrays;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.File;
class myRead{
public static void main(String[] args) throws FileNotFoundException, IOException {
File myFile = new File("test.txt");
readProductDataFile(myFile);
}
public static String[] readProductDataFile(File inputFile) throws FileNotFoundException, IOException{
BufferedReader myReader = new BufferedReader(new FileReader("test.txt"));
String numberOfElements = myReader.readLine();
//this is the first line which contains the number "10"
//System.out.println(numberOfElements);
String secondLine = myReader.readLine();
//this is the second line which contains your data, split it using "#" as a delimiter
String[] strArray = secondLine.split("#");
//System.out.println(Arrays.toString(strArray));
//System.out.println(strArray[0]);
String thirdLine = myReader.readLine();
//this is the third line which contains your data, split it using "#" as a delimiter
String[] dataArray = thirdLine.split("#");
//combine arrays
String[] combinedArray = new String[strArray.length];
for (int i=0;i<strArray.length;i++) {
combinedArray[i]=strArray[i]+"_"+dataArray[i];
System.out.println(combinedArray[i]);
}
return combinedArray;
}
}
OUTPUT
PA/1234_153
PV/5732_25
Au/9271_172
DT/9489_95
HY/7195_235
ZR/7413_159
bT/4674_725
LR/4992_629
Xk/8536_112
kD/9767_559
You don't even need the first line. Just read the second line directly into a single string and then split it by using String,split() method.
Read more for split method here.
You could use something like this (Be aware that i can't test it at the moment)
BufferedReader in = null;
try {
in = new BufferedReader(new FileReader("fileeditor.txt"));
String read = null;
String firstLine=in.readLine();
//reads the first line
while ((read = in.readLine()) != null) {
// reads all the other lines
read = in.readLine();
String[] splited = read.split("#");
//split the readed row with the "#" character
for (String part : splited) {
System.out.println(part);
}
}
} catch (IOException e) {
System.out.println("There was a problem: " + e);
e.printStackTrace();
} finally {
try {
//close file
in.close();
} catch (Exception e) {
}
}
This is how you can do it using Java (don't forget to import):
public static Product[] readProductDataFile(File inputFile){
Scanner s = new Scanner(inputFile);
String data = "";
while(s.hasNext())
data += s.nextLine();
String[] dataArray = data.split("#");
}
You can try this way ..
Reading line by line and storing each row in a array.
Use while storing so it will split and save .
String[] strArray = secondLine.split("#");
Now use the for loop and concat the values as u wish and save ina third array .
For(int i=0 ;i< file.readline;i++)
{
string s = a[customerid];
s.concat(a[productid]);
a[k] =s;
}

JAVA Reading from file word by word using BufferedReader

I have to read from a file Author|Name|Year I need to store this information into class nodes. I must use BufferedReader and FileReader.
public class Book {
String author, name;
int years;
}
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws Exception{
Book book1 = new Book();
FileReader file = new FileReader("C:/Users/ZatoIndustries/Desktop/failas.txt");
BufferedReader reader = new BufferedReader(file);
String text = "";
String line = reader.readLine();
}
}
Input looks like:
A|bbbb|2002
B|cccc|2001
A|dddd|2000
After you read line by line:
String line = reader.readLine();
split each line by |:
String[] words = line.split("\\|");
you can then assign each of these to a descriptive variable, if you'd like:
String year = words[2]
This is the easiest way to do this, though you could have a look at Scanner for something more complicated.
I think you should use Scanner Class with next() Method ,this will be easier .

Incorrect Output from CSV File

import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.ArrayList;
/**
* Write a description of class ReadInCsv here.
*
* #author (Kevin Knapp)
* #version (10-10-2013)
*/
public class ReadInCsv
{
public static void main(String[] args)
{
String csvName = "Countries.csv";
File csvFile = new File(csvName);
ArrayList<String> nameList = new ArrayList<>();
ArrayList<String> popList = new ArrayList<>();
ArrayList<String> areaList = new ArrayList<>();
ArrayList<String> gdpList = new ArrayList<>();
ArrayList<String> litRateList = new ArrayList<>();
try
{
Scanner in = new Scanner(csvFile).useDelimiter(",");
while (in.hasNext())
{
String name = in.next();
nameList.add(name);
String pop = in.next();
popList.add(pop);
String area = in.next();
areaList.add(area);
String gdp = in.next();
gdpList.add(gdp);
String litRate = in.next();
litRateList.add(litRate);
}
in.close();
System.out.println(nameList);
System.out.println(popList);
System.out.println(areaList);
System.out.println(gdpList);
System.out.println(litRateList);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
}
}
So im trying to read from a csv file and as it goes through it should add each scanned instance into a array list (im going to reference each element from these lists at a later point), but my outputs show that as soon as it reads something and adds it, it skips to the next line before reading the next string, i need it to read straight across, not diagonally
im sure im just missing something very simple, I just began learning java about a week ago, thanks for the help
A big problem with this method is that unless each line in the file ends in a comma, newlines will not be delimited. A better way is to read each line in, split on commas, and add the values to the ArrayLists one line at a time:
Scanner in = new Scanner(csvFile);
while (in.hasNextLine()) {
String[] fields = in.nextLine().split(",");
if (fields.length == 5) {
nameList.add(fields[0]);
popList.add(fields[1]);
areaList.add(fields[2]);
gdpList.add(fields[3]);
litRateList.add(fields[4]);
} else {
// Bad line...do what you want to show error here
}
}
An even better way is to use a Java library dedicated to reading CSV files. A quick Google search should turn up some good ones.

Categories