I\'ve got a file from a vendor that has 115 fixed-width fields per line. How can I parse that file into the 115 fields so I can use them in my code?
My first thought
Here is a basic implementation I use:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
public class FlatFileParser {
public static void main(String[] args) {
File inputFile = new File("data.in");
File outputFile = new File("data.out");
int columnLengths[] = {7, 4, 10, 1};
String charset = "ISO-8859-1";
String delimiter = "~";
System.out.println(
convertFixedWidthFile(inputFile, outputFile, columnLengths, delimiter, charset)
+ " lines written to " + outputFile.getAbsolutePath());
}
/**
* Converts a fixed width file to a delimited file.
*
* This method ignores (consumes) newline and carriage return
* characters. Lines returned is based strictly on the aggregated
* lengths of the columns.
*
* A RuntimeException is thrown if run-off characters are detected
* at eof.
*
* @param inputFile the fixed width file
* @param outputFile the generated delimited file
* @param columnLengths the array of column lengths
* @param delimiter the delimiter used to split the columns
* @param charsetName the charset name of the supplied files
* @return the number of completed lines
*/
public static final long convertFixedWidthFile(
File inputFile,
File outputFile,
int columnLengths[],
String delimiter,
String charsetName) {
InputStream inputStream = null;
Reader inputStreamReader = null;
OutputStream outputStream = null;
Writer outputStreamWriter = null;
String newline = System.getProperty("line.separator");
String separator;
int data;
int currentIndex = 0;
int currentLength = columnLengths[currentIndex];
int currentPosition = 0;
long lines = 0;
try {
inputStream = new FileInputStream(inputFile);
inputStreamReader = new InputStreamReader(inputStream, charsetName);
outputStream = new FileOutputStream(outputFile);
outputStreamWriter = new OutputStreamWriter(outputStream, charsetName);
while((data = inputStreamReader.read()) != -1) {
if(data != 13 && data != 10) {
outputStreamWriter.write(data);
if(++currentPosition > (currentLength - 1)) {
currentIndex++;
separator = delimiter;
if(currentIndex > columnLengths.length - 1) {
currentIndex = 0;
separator = newline;
lines++;
}
outputStreamWriter.write(separator);
currentLength = columnLengths[currentIndex];
currentPosition = 0;
}
}
}
if(currentIndex > 0 || currentPosition > 0) {
String line = "Line " + ((int)lines + 1);
String column = ", Column " + ((int)currentIndex + 1);
String position = ", Position " + ((int)currentPosition);
throw new RuntimeException("Incomplete record detected. " + line + column + position);
}
return lines;
}
catch (Throwable e) {
throw new RuntimeException(e);
}
finally {
try {
inputStreamReader.close();
outputStreamWriter.close();
}
catch (Throwable e) {
throw new RuntimeException(e);
}
}
}
}