【发布时间】:2016-07-08 20:52:54
【问题描述】:
我必须使用 IBM 创建的 CSVReader 并根据我的要求进行更改。我是 java 新手,除了#1 不知道怎么做,我的要求是:
- 通过命令行获取 CSV
- 添加主方法
- 用双引号将每一行括起来
- 输出一个新的 CSV
例如。输入
乔丹,迈克尔,J,“,23
前任。输出
"乔丹,迈克尔,J,"",23"
背景信息:此程序将被添加到 shell 脚本中,正在添加功能,因为如果输入单个双引号,csv 会损坏
代码如下:
package Scripts;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
public class CSVReader
{
private BufferedReader br;
private boolean hasNext = true;
private static char separator = ' ';
private static char quotechar = ' ';
public static final char DEFAULT_SEPARATOR = ',';
public static final char DEFAULT_QUOTE_CHARACTER = '"';
public static void main(final String[] args) throws IOException {
final String csvFile = args[0];
final ArrayList<String[]> allElements = new ArrayList<String[]>();
final CSVReader csvReader = new CSVReader(br, separator, quotechar, csvFile);
csvTransformer.readAll();
csvTransformer.close();
}
public CSVReader(final Reader reader) throws FileNotFoundException {
this(reader, DEFAULT_SEPARATOR);
}
public CSVReader(final Reader reader, final char separator) throws FileNotFoundException {
this(reader, separator, DEFAULT_QUOTE_CHARACTER, null);
}
public CSVReader(final Reader reader, final char separator, final char quotechar, final String csvFile) throws FileNotFoundException {
CSVTransformer.br = new BufferedReader(new FileReader(csvFile));
this.separator = separator;
this.quotechar = quotechar;
}
/**
* Reads the entire file into a List with each element being a String[] of tokens.
*
* return a List of String[], with each String[] representing a line of the file.
*/
public List readAll() throws IOException
{
List allElements = new ArrayList();
while (hasNext)
{
String[] nextLineAsTokens = readNext();
if (nextLineAsTokens != null)
allElements.add(nextLineAsTokens);
}
return allElements;
}
/**
* Reads the next line from the buffer and converts to a string array.
*
* return a string array with each comma-separated element as a separate entry.
*/
public String[] readNext() throws IOException {
String nextLine = getNextLine();
return hasNext ? parseLine(nextLine) : null;
}
/**
* Reads the next line from the file.
*
* return the next line from the file without trailing newline
*/
private String getNextLine() throws IOException {
String nextLine = br.readLine();
if (nextLine == null) {
hasNext = false;
}
return hasNext ? nextLine : null;
}
/**
* Parses an incoming String and returns an array of elements.
*
* @param nextLine
* the string to parse
* @return the comma-tokenized list of elements, or null if nextLine is null
* @throws IOException if bad things happen during the read
*/
private String[] parseLine(String nextLine) throws IOException {
if (nextLine == null) {
return null;
}
List tokensOnThisLine = new ArrayList();
StringBuffer sb = new StringBuffer();
boolean inQuotes = false;
do {
if (inQuotes) {
// continuing a quoted section, reappend newline
sb.append("\n");
nextLine = getNextLine();
if (nextLine == null)
break;
}
for (int i = 0; i < nextLine.length(); i++) {
char c = nextLine.charAt(i);
if (c == quotechar) {
// this gets complex... the quote may end a quoted block, or escape another quote.
// do a 1-char lookahead:
if(inQuotes) // we are in quotes, therefore there can be escaped quotes in here.
&& nextLine.length() > (i+1) // there is indeed another character to check.
&& nextLine.charAt(i+1) == quotechar )
{ // ..and that char. is a quote also.
// we have two quote chars in a row == one quote char, so consume them both and
// put one on the token. we do *not* exit the quoted text.
sb.append(nextLine.charAt(i+1));
i++;
}
else
{
inQuotes = !inQuotes;
}
}
else if (c == separator && !inQuotes) {
tokensOnThisLine.add(sb.toString());
sb = new StringBuffer(); // start work on next token
}
else {
sb.append(c);
}
}
} while (inQuotes);
tokensOnThisLine.add(sb.toString());
return (String[]) tokensOnThisLine.toArray(new String[0]);
}
public void close() throws IOException {
br.close();
}
}
on
【问题讨论】:
标签: java csv parsing escaping double-quotes