# Converting a text file to a CSV file

I'm attempting to learn more about Java and have created a method that takes a text file with stdout (space separated file) and converts it to a CSV file. I was attempting to use standard Java SE version 8.

Is there a better, more efficient, way of doing this?

The logic is:

1. Open file
2. Read file by line into string so it can be split
3. Split string removing spaces, back into array
4. Join with StringJoiner using ,
5. Convert back to string to remove leading ,
6. Update final array to be returned

Method to open file:

public void OpenFile(String fileName)
{
try
{
subFile = new Scanner (new File(fileName));
}
catch (Exception e)
{
System.out.println("File dosn't exist.");
}
}


Method to convert:

    public String[] TextToCsvArray(String[] fileArray)
{
int i=0;
while(subFile.hasNext())
{
String line = subFile.nextLine();
String[] split = line.split("\\s+");
StringJoiner joiner = new StringJoiner(",");

for (String strVal: split)

line = joiner.toString();
line = line.startsWith(",") ? line.substring(1) : line;
fileArray[i++] = line;
}
return fileArray;
}

• I will do the same way that you do, except there will be bugs since you are mutating params fileArray and you don't know the size of the array :)
– Hendrik T
Nov 13 '16 at 3:59

Since you are using Java 8 it is good to use the great streaming methods it give you. You can write your code simply like the following:

 public static void main(String[] args) {
String fileName = "./a.txt";
try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
String result = stream.map(s -> s.split("\\s+"))
.map(s -> Arrays.stream(s).collect(Collectors.joining(","))+"\n")
.collect(Collectors.joining());
System.out.println(result);

} catch (IOException e) {
e.printStackTrace();
}


The final result is stored in result and you just need simply to write it into the file!

• Thanks Guys, all these answers have helped me gain more understanding, wasn't aware of a number of features that have been suggested... thanks for the advice. :) Nov 13 '16 at 9:09
• Pooya, If I needed to remove the first "," off each line much like: line = line.startsWith(",") ? line.substring(1) : line; how would you suggest to put it into the stream.map command??? Nov 13 '16 at 23:33
• @Graham: in the second map statement you can put your logic although it may look bit more complicated and probably cannot fit in single lambda expression
– Pooya
Nov 14 '16 at 1:36

If your input is already separated correctly by spaces, it seems all you need to do is to convert those into commas and you're good. I'm not sure you need to go to/from arrays.

I would replace the code inside the loop:

{
String line = subFile.nextLine();
String[] split = line.split("\\s+");
StringJoiner joiner = new StringJoiner(",");

for (String strVal: split)

line = joiner.toString();
line = line.startsWith(",") ? line.substring(1) : line;
fileArray[i++] = line;
}


with this:

{
String line = subFile.nextLine();
line.trim().replaceAll(" +", " "); //check for double spaces
line.replace(' ', ',');   //replace space with comma
fileArray[i++] = line;
}


Oh, and check for the array size like someone else mentioned.

• Come to think of it, you could probably consolidate the 2 replace lines also:
– TDWebDev
Nov 13 '16 at 6:07
• I like the combination of triming and replacing here, thanks for the tips :) Nov 13 '16 at 9:10

Question: is there a better, more efficent, way of doing this...?

At what point do you call Scanner.close()? When you're dealing with input streams, you're supposed to close them when you're done.

For this reason, I'm not crazy about breaking OpenFile into a separate method... at least not in that way.

It's good to break big chunks of logic into smaller, more manageable bits, but try something like this approach instead...

public Scanner openFile(String fileName) {
try {
return new Scanner(new File(fileName));
} catch (Exception e) {
throw new IllegalArgumentException("Specified file doesn't exist:  " + fileName);
}
}


But as far as closing your streams -- I like try with resources.

try (Scanner scanner = openFile(filename)) {