我有一个132 kb的文件(你真的不能说它很大)而且我正在尝试从Scala REPL中读取它,但是我无法读取过去的2048个字符,因为它给了我一个{{1}异常
以下是我采取的步骤:
java.nio.charset.MalformedInputException
知道可能出现什么问题吗?
-
显然问题是该文件不是UTF编码的
我把它保存为UTF并且一切正常,我只是在迭代器上发出mkString并检索文件的全部内容
奇怪的是,这个错误只会引起前2048个字符的传递......
答案 0 :(得分:5)
如果没有该文件,则无法确定,但异常文档表明,当输入字节序列对于给定的字符集不合法,或者输入字符序列不是合法的16位Unicode序列时,它会被抛出。 (MalformedInputException javadoc)
我怀疑在2049年遇到的第一个字符对于您环境中的默认JVM字符编码无效。考虑使用fromFile.
如果应用程序是跨平台的,您应该知道JVM上的默认字符编码确实因平台而异,因此如果您使用特定编码进行操作,则要么在启动时将其显式设置为命令行参数您的应用程序,或使用适当的重载在每次调用时指定它。
答案 1 :(得分:4)
每次在同一个迭代器上调用take
两次,所有投注都会关闭。迭代器本质上是势在必行的,将它们与功能习语混合起来最多是冒险的。您在标准库中遇到的大多数迭代器在这方面往往表现得相当好,但是一旦您使用了take
,drop
或filter
等。 ,你处于不确定行为的土地上,原则上任何事情都可能发生。
来自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