I have a problem and wanted to ask if someone can help me. I have a Java application that processes CSV files. The files have a semi-colon as a "delimiter". Now instead of semicolons I would like to use pipe "|" as the "delimiter". What is the best way to do this?
I have already informed myself in the library or class "org.apache.commons.csv.CSVRecord". Unfortunately couldn't find anything here.
I used for parsing Spring Batch with the class FlatItemReaderBuilder.
You can also use Spring Batch classes in non Spring application.
Here you can find an example:
https://www.petrikainulainen.net/programming/spring-framework/spring-batch-tutorial-reading-information-from-a-file/
you could use Scanner or FileInputStream
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
public class ReadDelimited {
public static void main(String[] args) {
Scanner sc = null;
try {
sc = new Scanner(new File("D:\\acct.csv"));
// Check if there is another line of input
while(sc.hasNextLine()){
String str = sc.nextLine();
// parse each line using delimiter
parseData(str);
}
} catch (IOException exp) {
// TODO Auto-generated catch block
exp.printStackTrace();
}finally{
if(sc != null)
sc.close();
}
}
private static void parseData(String str){
String acctFrom, acctTo, amount;
Scanner lineScanner = new Scanner(str);
lineScanner.useDelimiter("|");
while(lineScanner.hasNext()){
acctFrom = lineScanner.next();
acctTo = lineScanner.next();
amount = lineScanner.next();
System.out.println("Account From- " + acctFrom + " Account To- " + acctTo +
" Amount- " + amount);
}
lineScanner.close();
}
}
reference Code original link
or if File is not too large get the read the File in a string Divide it into a String array by splitting by line break and then future splitting using the delimiter of choice something like the code below.
public static void main(String[] args) throws IOException {
FileInputStream fileInputStream=new FileInputStream("j:\\test.csv");
String s1=new String(fileInputStream.readAllBytes());
String[] lineArray=s1.split("\n");
List<String[]> separatedValues=new ArrayList<>();
for (String line: lineArray) {
separatedValues.add(line.split("\\|"));
}
for (String[] s: separatedValues) {
for (String s2:s ) {
System.out.print(s2+" ");
}
System.out.println("");
}
fileInputStream.close();
}
Code Output Link
Original CSV
Related
I'm new to Java and I have to read from a file, and then convert what I have read into variables. My file consists of a fruit, then a price and it has a long list of this. The file looks like this:
Bananas,4
Apples,5
Strawberry,8
...
Kiwi,3
So far I have created two variables(double price and String name), then set up a scanner that reads from the file.
public void read_file(){
try{
fruits = new Scanner(new File("fruits.txt"));
print_file();
}
catch(Exception e){
System.out.printf("Could not find file\n");
}
}
public void print_file(){
while(fruits.hasNextLine()){
String a = fruits.nextLine();
System.out.printf("%s\n", a);
return;
}
}
Currently I am only able to print out the entire line. But I was wondering how I could break this up to be able to store the lines into variables.
So your string a has an entire line like Apples,5. So try to split it by comma and store it into variables.
String arr[] = a.split(",");
String name = arr[0];
int number = Integer.parseInt(arr[1]);
Or if prices are not integers, then,
double number = Double.parseDouble(arr[1]);
Using java 8 stream and improved file reading capabilities you can do it as follows. it stores item and count as key value pair in a map. It is easy to access by key afterwards.
I know this Maybe too advance but eventually this will help you later when getting to know new stuff in java.
try (Stream<String> stream = Files.lines(Paths.get("src/test/resources/items.txt"))) {
Map<String, Integer> itemMap = stream.map(s -> s.split(","))
.collect(toMap(a -> a[0], a -> Integer.valueOf(a[1])));
System.out.println(itemMap);
} catch (IOException e) {
e.printStackTrace();
}
output
{Apples=5, Kiwi=3, Bananas=4, Strawberry=8}
You can specify a delimiter for the scanner by calling the useDelimiter method, like:
public static void main(String[] args) {
String str = "Bananas,4\n" + "Apples,5\n" + "Strawberry,8\n";
try (Scanner sc = new Scanner(str).useDelimiter(",|\n")) {
while (sc.hasNext()) {
String fruit = sc.next();
int price = sc.nextInt();
System.out.printf("%s,%d\n", fruit, price);
}
} catch (Exception e) {
e.printStackTrace(System.out);
}
}
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Test {
public static void main(String[] args) {
BufferedReader reader;
try {
reader = new BufferedReader(new FileReader(
"C://Test/myfile.txt")); //Your file location
String line = reader.readLine(); //reading the line
while(line!=null){
if(line!=null && line.contains(",")){
String[] data = line.split(",");
System.out.println("Fruit:: "+data[0]+" Count:: "+Integer.parseInt(data[1]));
}
//going over to next line
line = reader.readLine();
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
I am trying to make simple one-Class code to copy some definite files (photos) from one folder to another according to a list. The list is kept in separate txt file.
Finally I've got file not found error, so I divided entire code into parts and tested each of them with console output.
And that what I found in scanner while loop:
So the code:
import java.io.File;
import java.util.Scanner;
import java.io.FileNotFoundException;
public class Sandy2 {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
File f = new File("D:\\\\Javasorter\\List.txt");
Scanner in;
in = new Scanner(f).useDelimiter("[?! .,;:\t\r\n\f\'\"]");
String word, pathbuf1, pathbuf2;
while (in.hasNext()) {
word = in.next().toLowerCase();
System.out.println(word);
Thread.sleep(1000);
pathbuf1 = "\\IMG_" + word + ".CR2";
pathbuf2 = "\\IMG_" + word + ".CR2";
System.out.println(pathbuf1);
System.out.println(pathbuf2);
}
}
}
Expected output:
9452
\IMG_9452.CR2
\IMG_9452.CR2
9475
\IMG_9475.CR2
\IMG_9475.CR2
and so on until list has next, but
Output:
9452
\IMG_9452.CR2
\IMG_9452.CR2
\IMG_.CR2
\IMG_.CR2
9475 \IMG_9475.CR2
\IMG_9475.CR2
\IMG_.CR2
\IMG_.CR2
and so on///
Copying command is added in the same loop in full version program, where "\IMG_9452.CR2" is attached to path srting
So, after the first file copied I got error, because of course there is no "IMG_.CR2" file.
Does anybody know why \IMG_.CR2 doubles in each loop iteration?
Many thanks!
Your problem is in the .useDelimiter("[?! .,;:\t\r\n\f\'\"]"), because Scanner will read spaces between lines as string object, so you have to remove it or change it if you still need to use Delimiter.
Also, You can write the file path with forward slashes / then it will be more readable and OS independent, and try to use try-with-resource to prevent source leak.
Consider this code:
public static void main(String[] args) throws Exception {
try (Scanner in = new Scanner(new File("D:/Javasorter/List.txt"))) {
// in.useDelimiter("[?! .,;:\t\r\n\f\'\"]");
String word, pathbuf1, pathbuf2;
while (in.hasNext()) {
word = in.next().toLowerCase();
System.out.println(word);
Thread.sleep(1000);
pathbuf1 = "\\IMG_" + word + ".CR2";
pathbuf2 = "\\IMG_" + word + ".CR2";
System.out.println(pathbuf1);
System.out.println(pathbuf2);
}
}
}
If you want to use Delimiter for some cases, you can use string trim and then check if string is empty, like:
public static void main(String[] args) throws Exception {
try (Scanner in = new Scanner(new File("D:/Javasorter/List.txt"))) {
in.useDelimiter("[?! .,;:\t\r\n\f\'\"]");
String word, pathbuf1, pathbuf2;
while (in.hasNext()) {
word = in.next().trim().toLowerCase();
if (!word.isEmpty()) {
System.out.println(word);
Thread.sleep(1000);
pathbuf1 = "\\IMG_" + word + ".CR2";
pathbuf2 = "\\IMG_" + word + ".CR2";
System.out.println(pathbuf1);
System.out.println(pathbuf2);
}
}
}
}
remove the variable pathbuf2 completely and you will not have any more of the duplicates
I have to write code that will reverse the order of the string and write it in a new file. For example :
Hi my name is Bob.
I am ten years old.
The reversed will be :
I am ten years old.
Hi my name is Bob.
This is what I have so far. Not sure what to write for the outWriter print statement. Any help will be appreciated. Thanks!
import java.io.*;
import java.util.ArrayList;
import java.util.Scanner;
public class FileRewinder {
public static void main(String[] args) {
File inputFile = new File("ascii.txt");
ArrayList<String> list1 = new ArrayList<String>();
Scanner inputScanner;
try {
inputScanner = new Scanner(inputFile);
} catch (FileNotFoundException f) {
System.out.println("File not found :" + f);
return;
}
while (inputScanner.hasNextLine()) {
String curLine = inputScanner .nextLine();
System.out.println(curLine );
}
inputScanner.close();
File outputFile = new File("hi.txt");
PrintWriter outWriter = null;
try {
outWriter = new PrintWriter(outputFile);
} catch (FileNotFoundException e) {
System.out.println("File not found :" + e);
return;
}
outWriter.println(???);
outWriter.close();
}
}
My suggestion is read entire file first and store sentences(you can split by .) in a LinkedList<String>(this will keep insertion order)
Then use Iterator and get sentences in reverse order. and write them into a file. make sure to put . just after each sentence.
After System.out.println(curLine ); add list1.add(curline); that will place your lines of text into your list.
At the end create a loop over list1 backwards:
for(int i = list1.size() - 1 , i > 0, --i) {
outWriter.println(list1[i]);
}
If the file contains an amount of lines which can be loaded into the memory. You can read all lines into a list, reverse the order of the list and write the list back to the disk.
public class Reverse {
static final Charset FILE_ENCODING = StandardCharsets.UTF_8;
public static void main(String[] args) throws IOException {
List<String> inLines = Files.readAllLines(Paths.get("ascii.txt"), FILE_ENCODING);
Collections.reverse(inLines);
Files.write(Paths.get("hi.txt"), inLines, FILE_ENCODING);
}
}
I'm having some problems reading some numbers separated by ":" from a txt file in java.
This is what i have so far:
public static void main(String []args) {
Scanner keyb = new Scanner(System.in);
System.out.print("Enter input file name: ");
String inputFile = keyb.nextLine();
System.out.print("Enter output file name: ");
String outputFile = keyb.nextLine();
File file = new File(inputFile);
try {
Scanner sc = new Scanner (file);
while (sc.hasNextLine()) {
System.out.println(sc.nextLine());
}
} catch(FileNotFoundException e) {
System.out.println("File not found!");
}
}
File numbers.txt
12.1:15.42
0.23:0.25
-9.2:-8.1
13.5:15.9
1024:1023.9
1.0e-3:1.0e-4
15.92:-9.35
18.26:6.4
55.931:55.930
256:512
I dont understand why its not being read...any help would be much appreciated! thank you!
I tried testing your program and got correct output. Take a look
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Read {
public static void main(String[] args) {
File file = new File("numbers.txt");
try {
#SuppressWarnings("resource")
Scanner sc = new Scanner(file);
while (sc.hasNextLine()) {
System.out.println(sc.nextLine());
}
} catch (FileNotFoundException e) {
System.out.println("File not found!");
}
}
}
Output:
12.1:15.42
0.23:0.25
-9.2:-8.1
13.5:15.9
1024:1023.9
1.0e-3:1.0e-4
15.92:-9.35
18.26:6.4
55.931:55.930
256:512
I recommend using java.util.BufferedReader to read a file. There generally easy to use compared to the Scanner class.
...
BufferedReader br = new BufferedReader(new FileReader(inputFile));
String inLine; //Buffer used to store the current line
while ((inLine = br.readLine()) != null) //keep reading until we reach the end of file
{
System.out.println(inLine);
}
Tutorial: Java >> BufferedReader
Make use of the split method in the string class and equate the output to an array,each index will have a different number if they are all indeed seperated by the same character that you have specified above: http://docs.oracle.com/javase/7/docs/api/java/lang/String.html and http://www.coderanch.com/t/385246/java/java/split-method-String-API might help but I strongly recon u download all the APIs
I was asked to write an assignment wherein the user would be prompted to input a key and/or a value.
So far, here is my code:
import java.util.Scanner;
import java.io.*;
class bTree
{
//Fields
static Scanner input = new Scanner(System.in);
static boolean done = false;
public static void main(String args[])throws Exception
{
FileWriter fWriter = new FileWriter("data.txt");
do
{
System.out.print("Enter command: ");
String enter[] = input.nextLine().split(" ", 3);
if(enter[0].toLowerCase().equals("insert"))
{
fWriter.write(enter[1] + "\n" + enter[2] + "\n");
fWriter.flush();
}
else if(enter[0].toLowerCase().equals("select"))
{
FileReader fReader = new FileReader("data.txt");
Scanner fileInput = new Scanner(fReader);
while(fileInput.hasNext() && done == false)
{
if(fileInput.nextLine().equals(enter[1]))
{
System.out.println(fileInput.nextLine());
done = true;
}
else
{
fileInput.nextLine();
}
}
done = false;
}
else if(enter[0].toLowerCase().equals("update"))
{
fWriter.write(enter[2]);
fWriter.flush();
}
else if(enter[0].toLowerCase().equals("exit"))
{
System.exit(0);
}
}
while(true);
}
}
Problem: When i open the data.txt, there are no spaces. So if i enter "insert 1001 gen" and "10001 genny", in notepad, it would come out as "1001gen10001genny". Any suggestions?
The problem is that notepad.exe is picky about line endings, and there are many possibilities. When you write "\n" to a FileWriter, it writes a single character, namely '\n'. But notepad expects the sequence "\r\n" instead. It shows a single "\n" as nothing.
Here is your code, slightly modified to work around some pitfalls.
package so7696816;
import java.io.FileReader;
import java.io.PrintWriter;
import java.util.Locale;
import java.util.Scanner;
public class Excercise {
public static void main(String args[]) throws Exception {
final Scanner input = new Scanner(System.in);
PrintWriter fWriter = new PrintWriter("data.txt");
while (true) {
System.out.print("Enter command: ");
String enter[] = input.nextLine().split(" ", 3);
final String command = enter[0].toLowerCase(Locale.ROOT);
if (command.equals("insert")) {
fWriter.println(enter[1]);
fWriter.println(enter[2]);
fWriter.flush();
} else if (command.equals("select")) {
FileReader fReader = new FileReader("data.txt");
Scanner fileInput = new Scanner(fReader);
while (fileInput.hasNextLine()) {
String key = fileInput.nextLine();
String value = fileInput.nextLine();
if (key.equals(enter[1])) {
System.out.println(value);
break;
}
}
fReader.close(); // don't leave files open
} else if (command.equals("update")) {
fWriter.write(enter[2]);
fWriter.flush();
} else if (command.equals("exit")) {
return;
} else {
System.err.println("Unknown command: " + command);
}
}
}
}
Remarks:
I used a PrintWriter instead of a FileWriter to get the line endings correct.
For the select command I closed the fReader after using it.
I avoided to type enter[0].toLowerCase() multiple times.
I used the proper variant of toLowerCase.
I added error handling for unknown commands.
I rewrote the select command to be a little more concise.
The problem is String enter[] = input.nextLine().split(" ", 3);, it kills the Spaces. So append a space after each array entry or write an additional " " everytime you use fWriter.write.
look here
As already stated the line feed character is incorrect for notepad. Alternatively you could wrap that FileWriter in a BufferedWriter and use the newLine method to always insert the correct line feed.
I think you are running your program in UNIX. In unix system "\r\n" is the line feed.
If you are running your program in Windows, I think the file should contain something like this.
1001
gen
10001
genny