尝试读取整个文件时出现MalformedInputException

时间:2012-11-11 00:40:30

标签: file scala file-io

我有一个132 kb的文件(你真的不能说它很大)而且我正在尝试从Scala REPL中读取它,但是我无法读取过去的2048个字符,因为它给了我一个{{1}异常

以下是我采取的步骤:

java.nio.charset.MalformedInputException

知道可能出现什么问题吗?

-

显然问题是该文件不是UTF编码的

我把它保存为UTF并且一切正常,我只是在迭代器上发出mkString并检索文件的全部内容

奇怪的是,这个错误只会引起前2048个字符的传递......

3 个答案:

答案 0 :(得分:5)

如果没有该文件,则无法确定,但异常文档表明,当输入字节序列对于给定的字符集不合法,或者输入字符序列不是合法的16位Unicode序列时,它会被抛出。 (MalformedInputException javadoc

我怀疑在2049年遇到的第一个字符对于您环境中的默认JVM字符编码无效。考虑使用fromFile.

的重载之一明确说明文件的字符编码

如果应用程序是跨平台的,您应该知道JVM上的默认字符编码确实因平台而异,因此如果您使用特定编码进行操作,则要么在启动时将其显式设置为命令行参数您的应用程序,或使用适当的重载在每次调用时指定它。

答案 1 :(得分:4)

每次在同一个迭代器上调用take两次,所有投注都会关闭。迭代器本质上是势在必行的,将它们与功能习语混合起来最多是冒险的。您在标准库中遇到的大多数迭代器在这方面往往表现得相当好,但是一旦您使用了takedropfilter等。 ,你处于不确定行为的土地上,原则上任何事情都可能发生。

来自the docs

  

特别重要的是要注意,除非另有说明,   在调用方法之后永远不应该使用迭代器。他们俩   最重要的例外也是唯一的抽象方法:next   和hasNext ......

     

def take(n: Int): Iterator[A] ...

     

重用:调用此方法后,应该丢弃迭代器   被调用,并只使用返回的迭代器。使用   旧迭代器未定义,可能会发生变化,并可能导致   也改变了新的迭代器。

因此,可能不值得尝试追踪到底出了什么问题。

答案 2 :(得分:4)

如果您只想将字节转换为普通拉丁语数据:

// File:
io.Source.fromFile(file)(io.Codec.ISO8859).mkString

// InputStream:
io.Source.fromInputStream(System.io)(io.Codec.ISO8859).mkString