2015-03-31 102 views
0

我想用Jackson的的CSV data format module解析CSV文件。使用Jackson的CSV數據格式模塊解析CSV文件中的CharConversionException

我試圖對他們的項目主頁給出的示例代碼(https://github.com/FasterXML/jackson-dataformat-csv

CsvMapper mapper = new CsvMapper(); 
mapper.enable(CsvParser.Feature.WRAP_AS_ARRAY); 
File csvFile = new File("input.csv"); 
MappingIterator<String[]> it = mapper.reader(String[].class).readValues(csvFile); 
while (it.hasNext()) { 
    String[] row = it.next(); 
    System.out.println(row) 
} 

這個小的代碼是給我錯誤

Exception in thread "main" java.io.CharConversionException: Invalid UTF-8 start byte 0x92 (at char #269, byte #-1) 
at com.fasterxml.jackson.dataformat.csv.impl.UTF8Reader.reportInvalidInitial(UTF8Reader.java:393) 
at com.fasterxml.jackson.dataformat.csv.impl.UTF8Reader.read(UTF8Reader.java:245) 
at com.fasterxml.jackson.dataformat.csv.impl.CsvReader.loadMore(CsvReader.java:438) 
at com.fasterxml.jackson.dataformat.csv.impl.CsvReader.hasMoreInput(CsvReader.java:475) 
at com.fasterxml.jackson.dataformat.csv.CsvParser._handleStartDoc(CsvParser.java:461) 
at com.fasterxml.jackson.dataformat.csv.CsvParser.nextToken(CsvParser.java:414) 
at com.fasterxml.jackson.databind.ObjectReader._bindAndReadValues(ObjectReader.java:1492) 
at com.fasterxml.jackson.databind.ObjectReader.readValues(ObjectReader.java:1335) 
at com.til.etwealth.etmoney.util.alok.main(alok.java:18) 

我能夠使用openCSV
我試圖讀取同一個文件通過互聯網上的這個錯誤找出來,但找不到有用的東西。請有人告訴我缺少什麼?

回答

1

很可能您正在閱讀的內容不是UTF-8編碼,而是使用其他內容,例如Latin-1(ISO-8859-1)。 我認爲你得到的錯誤信息不是很好,所以也許可以改進以提示可能的原因,因爲這是相對常見的問題。

要閱讀非Unicode編碼,您需要自己構造Reader(因爲無法可靠地自動檢測差異 - 儘管可能有Java庫可能使用啓發式技術來嘗試自動確定此問題):

mapper.readValues(new InputStreamReader(new FileInputStream(csvFile), "ISO-8859-1"); 

或者,無論用什麼來編碼文件,都應該指定要使用的UTF-8編碼。

還有其他可能的原因(如文件截斷),但不匹配的字符編碼是一個常見的原因。這裏主要的奇怪之處在於特定的字符代碼,它不是ISO-8859-x編碼(大多數?)中的可打印字符。

+0

我相信在我的文件沒有不可打印或特殊字符。我可以使用'openCVS'來讀取我的文件。 – 2015-04-10 10:42:36

+0

如果你有一個觸發這個文件的示例文件,最好在(https://github.com/FasterXML/jackson-dataformat-csv/)上提交一個錯誤報告。問題/)。 – StaxMan 2015-04-10 19:58:45

1

一種解決方法,這將在大多數情況下是導入Apache的蒂卡和使用AutoDetectReader(見)

試試這個:

//get a file stream in utf format for this file (since they are often not in utf by 
    Charset charset = new AutoDetectReader(new FileInputStream(file)).getCharset(); 
    String f = FileUtils.readFileToString(file, charset); 
    CsvMapper mapper = new CsvMapper(); 
    CsvSchema schema = CsvSchema.emptySchema().withHeader(); 
    MappingIterator<Map<String, String>> it = mapper.reader(Map.class).with(schema).readValues(f.getBytes()); 

在哪裏我也用阿帕奇百科全書將文件轉換爲一個字符串。這可以做到沒有Apache公共,只是谷歌它