Keep quotes when parsing csv - java

I know there is already a question related to this: How to keep quotes when parsing csv file? (But it's for C#)
Let's say I have a csv with values e.g:
12312414-DEF_234, "34-DE, 234-EG, 36354-EJ", 23
...
When I parse it with OpenCSV, it doesn't keep the quotes.
CSVReader reader = new CSVReader(new FileReader("../path.csv"), ',', '\"');
List<String[]> list = reader.readAll();
String[][] csvArray = new String[list.size()][];
csvArray = list.toArray(csvArray);
So, after I store all of the values into an array, when I try to print out the values (for checking), the quotes are not there.
...
System.out.println(csvArray[i][j]);
// output below
// 34-DE, 234-EG, 36354-EJ
How can I keep the quotes? The reason is because I am going to be changing some values, and need to re-output it back into a csv.

The CSVReader has to parse and remove the quotes, otherwise you wouldn't get one value 34-DE, 234-EG, 36354-EJ, but three values "34-DE, 234-EG and 36354-EJ". So it's OK that the quotes are being removed.
The CSVWriter should add them again for every value that needs quoting.
Have you tried to write the array back into a CSV? The value 34-DE, 234-EG, 36354-EJ - actually any value that contains a comma - should be quoted.

public static void readCSV(){
String csvFile = "input.csv";
BufferedReader br = null;
String line = "";
String splitter = ",";
try {
br = new BufferedReader(new FileReader(csvFile));
while ((line = br.readLine()) != null) {
// use comma as separator
String[] words = line.split(splitter);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

Related

BufferedReader returning columns instead of row

When I do this...
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(filename))) {
String line;
while ((line = bufferedReader.readLine()) != null) {
String[] data = line.split(",");
}
} catch (IOException e) {
e.printStackTrace();
}
If I print data[0], I get the first column instead of the first row. How can I modify it to return rows when I do data[0]?
When I did...
List<String> data;
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(filename))) {
data = bufferedReader.lines().collect(Collectors.toList());
} catch (IOException e) {
e.printStackTrace();
}
And do data.get(0), I get rows as expected, so why not with the first method?
In your first example, you read each line with bufferedReader.readLine(), which already gives you a row. Then you split the row at the , char, which gives you columns for the current row.
Your seconds example, using bufferedReader.lines() returns a Stream of rows, which you collect with .collect(Collectors.toList()). Each of that rows in your List still simply has a string with all the commas in it. So what you probably want is a 2D-Array or a List<List<String>>.
You can achieve this as follows:
try (BufferedReader br = new BufferedReader(new FileReader(filename))) {
final List<List<String>> table = br.lines()
.map(row -> Stream.of(row.split(","))
.collect(Collectors.toList()))
.collect(Collectors.toList());
System.out.println(table.get(0));
} catch (IOException e) {
e.printStackTrace();
}
while ((line = bufferedReader.readLine()) != null) {
String[] data = line.split(",");
}
In here you're fetching a single line, spliting it into parts by , and assigning to the data variable. At that time you have a single line processed, there is no way to refer row x as you only got one row. And that variable is defined inside of the while loop so it's state is only accessible during one given iteration.
In a CSV file, each line is a row. Splitting the lines is what gives you the columns. So if you want the rows, you do not need to split the lines, just print them out the way they are. For example to print out just the first row, all you need to do is
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(filename))) {
String firstRow = bufferedReader.readLine();
System.out.println(firstRow);
} catch (IOException e) {
e.printStackTrace();
}

reading file to list<integer>

I am trying to read a text file in that contains numbers separated by commas. the file is large and may contain up to a few thousand numbers. i need to add these numbers to a list
List<Integer> listIntegers = new ArrayList<Integer>();
what would be the best approach to take? I am currently reading in the file like this;
StringBuilder sb = new StringBuilder();
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("D:\\generated30-1.cav"));
String line = null;
while ((line = br.readLine()) != null)
{
sb.append(line.replaceAll(",",""));
if (sb.length() > 0)
{
sb.append("\n");
}
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
if (br != null)
{
br.close();
}
}
catch (IOException ex)
{
ex.printStackTrace();
}
}
String contents = sb.toString();
If the numbers are separated by commas, you should not be removing the commas. I would use a Scanner. I would use try-with-resources instead of an explicit close(). And I would split each line on comma (\\s* globs optional whitespace). Like,
List<Integer> listIntegers = new ArrayList<>();
File f = new File("D:\\generated30-1.cav");
try (Scanner sc = new Scanner(f)) {
while (sc.hasNextLine()) {
String line = sc.nextLine();
String[] tokens = line.split("\\s*,\\s*");
for (String token : tokens) {
listIntegers.add(Integer.parseInt(token));
}
}
} catch (Exception e) {
e.printStackTrace();
}
return listIntegers;
Since your input file does not contain spaces after the commas, then you should not be replacing the commas, as if you have multi digit numbers, you will not be able to differentiate between where the number starts and ends. Instead just append line:
sb.append(line);
And then you can do:
List<Integer> list = Arrays.stream(contents.split(","))
.map(Integer::valueOf)
.collect(toList());
Which will create a stream from the Array created by split and then map them to int's and then collect them to a List
I'd definitely try and leverage the Files.lines as of JDK8:
List<Integer> result;
try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
stream.map(s -> /* perform your mapping operation here */)
.collect(Collectors.toList());
} catch (IOException e) { e.printStackTrace(); }
reading:
Introduction to Java 8
Streams
Java 8 Map, Filter, and Collect Examples
The map method documentation

Assigning part of txt file to java variable

I have a txt file with the following output:
"CN=COUD111255,OU=Workstations,OU=Mis,OU=Accounts,DC=FLHOSP,DC=NET"
What I'm trying to do is read the COUD111255 part and assign it to a java variable. I assigned ldap to sCurrentLine, but I'm getting a null point exception. Any suggestions.
try (BufferedReader br = new BufferedReader(new FileReader("resultofbatch.txt")))
{
final Pattern PATTERN = Pattern.compile("CN=([^,]+).*");
try {
while ((sCurrentLine = br.readLine()) != null) {
//Write the function you want to do, here.
String[] tokens = PATTERN.split(","); //This will return you a array, containing the string array splitted by what you write inside it.
//should be in your case the split, since they are seperated by ","
}
System.out.println(sCurrentLine);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
}
});
You just need to read data from a file line by line and assign the line to your variable str. Refer to following link:
How to read a large text file line by line using Java?
Your code is almost correct. You are writing this string to standard output - what for? If I understand you right, what you need is simply this:
private static final Pattern PATTERN = Pattern.compile("CN=([^,]+).*");
public static String solve(String str) {
Matcher matcher = PATTERN.matcher(str);
if (matcher.matches()) {
return matcher.group(1);
} else {
throw new IllegalArgumentException("Wrong string " + str);
}
}
This call
solve("CN=COUD111255,OU=Workstations,OU=Mis,OU=Accounts,DC=FLHOSP,DC=NET")
gave me "COUD111255" as answer.
To read from .txt, use BufferedReader. To create a one, write:
BufferedReader br = new BufferedReader(new FileReader("testing.txt"));
testing.txt is the name of the txt that you're reading and must be in your java file. After initializing, you must continue as:
while ((CurrentLine = br.readLine()) != null) {
//Write the function you want to do, here.
String[] tokens = CurrentLine.split(","); //This will return you a array, containing the string array splitted by what you write inside it.
//should be in your case the split, since they are seperated by ","
}
You got tokens array which is = [CN=COUD111255,OU=Workstations OU=Mis,OU=Accounts,DC=FLHOSP,DC=NET].
So, now take the 0th element of array and make use of it. You got the CN=COUD111255, now! Leaving here not to give whole code.
Hope that helps !

Read file, replace string and create a new one with all content

I am trying to replace ? with - in my text document but just the ArrayList<String> is being written in the new file without all lines of the old one. How can I fix that?
File file = new File("D:\\hl_sv\\L09MF.txt");
ArrayList<String> lns = new ArrayList<String>();
Scanner scanner;
try {
scanner = new Scanner(file);
int lineNum = 0;
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
lineNum++;
if (line.contains("?")) {
line = line.replace("?", "-");
lns.add(line);
// System.out.println("I found it on line " + lineNum);
}
}
lines.clear();
lines = lns;
System.out.println("Test: " + lines);
FileWriter writer;
try {
writer = new FileWriter("D:\\hl_sv\\L09MF2.txt");
for (String str : lines) {
writer.write(str);
}
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I don't understand why you're storing the lines in a List to begin with. I would perform the transform and print while I read. You don't need to test for the presence of the ? (replace won't alter anything if it isn't present). And, I would also use a try-with-resources. Something like
File file = new File("D:\\hl_sv\\L09MF.txt");
try (PrintWriter writer = new PrintWriter("D:\\hl_sv\\L09MF2.txt");
Scanner scanner = new Scanner(file)) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
writer.println(line.replace('?', '-'));
}
} catch (Exception e) {
e.printStackTrace();
}
Examine this code:
if (line.contains("?")) {
line = line.replace("?", "-");
lns.add(line);
}
You are only adding the current line (with the replacement) if it had a ? in it, ignoring other lines. Restructure it to always add the existing line.
if (line.contains("?")) {
line = line.replace("?", "-");
}
lns.add(line);
Additionally, the part
if (line.contains("?"))
scans line to look for a ?, and then the code
line.replace("?", "-");
does the same thing, but this time also replacing any ? with -. You may as well scan line just once:
lns.add(line.replace("?", "-"));
Note that creating an ArrayList just to hold the new lines wastes a fair amount of memory if the file is large. A better pattern would be to write each line, modified if necessary, right after you read in the corresponding line.
Within your while loop you have an if statement checking the line which adds the altered line to the array. You also need to add the unaltered lines to the array.
This should fix your issue:
int lineNum = 0;
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
lineNum++;
if (line.contains("?")) {
line = line.replace("?", "-");
lns.add(line);
// System.out.println("I found it on line " + lineNum);
}
else{
lns.add(line);
}
Previously, you were only adding the line to your ArrayList if it contained a "?" character. You need to add the line to the ArrayList whether or not it contains "?"
I would use a different approach if I'm trying to work on the functionality you want to implement, please check this approach and tell me if this helps you :)
public void saveReplacedFile() {
//1. Given a file in your system
File file = new File("D:\\hl_sv\\L09MF.txt");
try {
//2. I will read it, not necessarily with Scanner, but use a BufferedReader instead
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
//3. Define a variable that will hold the value of each line
String line = null;
//and also the information of your file
StringBuilder contentHolder = new StringBuilder();
//why not get your line separator based on your O.S?
String lineSeparator = System.getProperty("line.separator");
//4. Check your file line by line
while ((line = bufferedReader.readLine()) != null) {
contentHolder.append(line);
contentHolder.append(lineSeparator);
}
//5. By this point, your contentHolder will contain all the data of your text
//But it is still a StringBuilder type object, why not convert it to a String?
String contentAsString = contentHolder.toString();
//6. Now we can replace your "?" with "-"
String replacedString = contentAsString.replace("?", "-");
//7. Now, let's save it in a new file using BufferedWriter :)
File fileToBeSaved = new File("D:\\hl_sv\\L09MF2.txt");
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(fileToBeSaved));
bufferedWriter.write(replacedString);
//Done :)
} catch (FileNotFoundException e) {
// Exception thrown if the file does not exist in your system
e.printStackTrace();
} catch (IOException e) {
// Exception thrown due to an issue with IO
e.printStackTrace();
}
}
Hope this is helpful. Happy coding :)
If you can use Java 8 then your code can be simplified to
try (PrintStream ps = new PrintStream("D:\\hl_sv\\L09MF2.txt");
Stream<String> stream = Files.lines(Paths.get("D:\\hl_sv\\L09MF.txt"))) {
stream.map(line -> line.replace('?', '-')).forEach(ps::println);
} catch (IOException e) {
e.printStackTrace();
}

In Java, I want to split an array into smaller arrays, the length of which varys with inputted text files

So far, I have 2 arrays: one with stock codes and one with a list of file names. What I want to do is input the .txt files from each of the file names from the second array and then split this input into: 1. Arrays for each file 2. Arrays for each part with each file.
I have this:
ImportFiles f1 = new ImportFiles("File");
for (String file : FileArray.filearray) {
if (debug) {
System.out.println(file);
}
try {
String line;
String fileext = "C:\\ASCIIpdbSKJ\\"+file+".txt";
importstart = new BufferedReader(new FileReader(fileext));
for (line = importstart.readLine(); line != null; line = importstart.readLine()) {
importarray.add (line);
if (debug){
System.out.println(importarray.size());
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
importarray.add ("End")
This approach works to create a large array of all the files, will it be easier to change the input method to split it as it is coming in or split the large array I have?
At this point, the stock code array is irrelevant. Once I have split the arrays down I know where I will go from there.
Thanks.
Edit: I am aware that this code is incomplete in terms of { } but it is only printstreams and debugging missed off.
If you want to get a map with a filename and all its lines from all the files, here are relevant code parts:
Map<String, List<String>> fileLines = new HashMap<String, List<String>>();
for (String file : FileArray.filearray)
BufferedReader reader = new BufferedReader(new FileReader(fileext));
List<String> lines = new ArrayList<String>();
while ((line = reader.readLine()) != null){
lines.add(line);
}
fileLines.put(file, lines);
}

Categories

Resources