【发布时间】:2012-11-17 11:33:50
【问题描述】:
我正在尝试解析 CSV 文件,最好使用 weka.core.converters.CSVLoader。 但是,我拥有的文件不是有效的 UTF-8 文件。 它主要是一个 UTF-8 文件,但一些字段值采用不同的编码, 所以没有整个文件有效的编码, 但无论如何我都需要解析它。 除了使用像 Weka 这样的 java 库之外,我主要在 Scala 中工作。 我什至无法读取使用 scala.io.Source 的文件: 例如
Source.
fromFile(filename)("UTF-8").
foreach(print);
抛出:
java.nio.charset.MalformedInputException: Input length = 1
at java.nio.charset.CoderResult.throwException(CoderResult.java:277)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:337)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:176)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:153)
at java.io.BufferedReader.read(BufferedReader.java:174)
at scala.io.BufferedSource$$anonfun$iter$1$$anonfun$apply$mcI$sp$1.apply$mcI$sp(BufferedSource.scala:38)
at scala.io.Codec.wrap(Codec.scala:64)
at scala.io.BufferedSource$$anonfun$iter$1.apply(BufferedSource.scala:38)
at scala.io.BufferedSource$$anonfun$iter$1.apply(BufferedSource.scala:38)
at scala.collection.Iterator$$anon$14.next(Iterator.scala:150)
at scala.collection.Iterator$$anon$25.hasNext(Iterator.scala:562)
at scala.collection.Iterator$$anon$19.hasNext(Iterator.scala:400)
at scala.io.Source.hasNext(Source.scala:238)
at scala.collection.Iterator$class.foreach(Iterator.scala:772)
at scala.io.Source.foreach(Source.scala:181)
我很高兴将所有无效字符扔掉或用一些虚拟字符替换它们。 我将有很多这样的文本以各种方式处理 并且可能需要将数据传递给各种第三方库。 一个理想的解决方案是某种全局设置,它将 导致所有低级 java 库忽略文本中的无效字节, 这样我就可以在不修改的情况下调用第三方库。
解决方案:
import java.nio.charset.CodingErrorAction
import scala.io.Codec
implicit val codec = Codec("UTF-8")
codec.onMalformedInput(CodingErrorAction.REPLACE)
codec.onUnmappableCharacter(CodingErrorAction.REPLACE)
val src = Source.
fromFile(filename).
foreach(print)
感谢 +Esailija 为我指明了正确的方向。 这将我带到How to detect illegal UTF-8 byte sequences to replace them in java inputstream? 它提供了核心的 java 解决方案。在 Scala 中,我可以通过使编解码器隐式来使其成为默认行为。我想我可以通过将其隐式编解码器定义放在包对象中来使其成为整个包的默认行为。
【问题讨论】:
-
在混乱中的某个地方,
CharsetDecoder的CodingErrorAction必须设置为IGNORE或REPLACE -
+Esailija 这就是我想到的解决方案。 Python scikit 库中的一些文本处理函数采用这个选项作为参数。我只是没有看到在 Java/Scala apis 中设置它的任何东西。
-
我在回答中使用了手工制作的解决方案,我对 java 或 scala 也一无所知
标签: java scala utf-8 character-encoding weka