8

私は132kbのファイルを持っていて(実際には大きいとは言えません)、Scala REPLから読み取ろうとしていますが、java.nio.charset.MalformedInputException例外が発生するため、2048文字を超えて読み取ることができません。

これらは私が取るステップです:

val it = scala.io.Source.fromFile("docs/categorizer/usig_calles.json") // this is ok
it.take(2048).mkString // this is ok too
it.take(1).mkString // BANG!

java.nio.charset.MalformedInputException: Input length = 1
at java.nio.charset.CoderResult.throwException(CoderResult.java:277)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:338)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
at java.io.InputStreamReader.read(InputStreamReader.java:184)

何が間違っている可能性がありますか?

-

どうやら問題は、ファイルがUTFエンコードされていないことでした

それをUTFとして保存し、すべてが機能します。イテレータでmkStringを発行するだけで、ファイルの内容全体が取得されます。

奇妙なことに、エラーは最初の2048文字を通過するだけで発生しました...

4

3 に答える 3

5

ファイルがないと確実ではありませんが、例外に関するドキュメントには、「入力バイトシーケンスが特定の文字セットに対して有効でない場合、または入力文字シーケンスが有効な16ビットUnicodeシーケンスでない場合」にスローされることが示されています。(MalformedInputException javadoc

2049年に最初に遭遇した文字は、環境内のデフォルトのJVM文字エンコードでは無効であると思われます。オーバーロードの1つを使用して、ファイルの文字エンコードを明示的に記述することを検討してください。fromFile.

アプリケーションがクロスプラットフォームである場合、JVMのデフォルトの文字エンコードはプラットフォームによって異なることを知っておく必要があります。したがって、特定のエンコードで操作する場合は、アプリケーションの起動時にコマンドラインパラメーターとして明示的に設定する必要があります。または、適切なオーバーロードを使用して、呼び出しごとに指定します。

于 2012-11-11T01:25:39.520 に答える
4

同じイテレータで2回コールtakeすると、すべてのベットがオフになります。イテレータは本質的に必須であり、それらを機能的なイディオムと混合することはせいぜい危険です。標準ライブラリで遭遇するイテレータのほとんどは、この点でかなり正常に動作する傾向がありますが、、、、、などを使用するtakedropfilter未定義の動作の土地になり、原則として何でも可能です。起こる。

ドキュメントから:

特に明記されていない限り 、メソッドを呼び出した後はイテレータを使用しないでください。2つの最も重要な例外は、唯一の抽象メソッドでもnext ありhasNextます。

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

再利用:このメソッドを呼び出した後、呼び出されたイテレータを破棄し、返されたイテレータのみを使用する必要があります。古いイテレータの使用は未定義であり、変更される可能性があり、新しいイテレータも変更される可能性があります。

したがって、ここで何が悪かったのかを正確に追跡することはおそらく価値がありません。

于 2012-11-11T01:42:17.253 に答える
4

バイトをプレーンラテンデータに変換したいだけの場合:

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

// InputStream:
io.Source.fromInputStream(System.io)(io.Codec.ISO8859).mkString
于 2014-06-15T13:35:17.477 に答える