Java学習5_Java NIOでjava.nio.charset.MalformedInputExceptionが報告されています。入力の長さ = 1 の例外
2022-02-22 10:32:40
Flumeを使用してファイルを読み込んでいるときに、以下のエラーが発生しました。
ERROR ({pool-4-thread-1} SpoolDirectorySource.java[run]:256) [2015-10-30 02:06:36,030] - FATAL: Spool Directory source r1: { spoolDir: /home/ hadoop/flumeSpool }: Uncaught exception in SpoolDirectorySource thread. restart or reconfigure Flume to continue processing.
java.nio.charset.MalformedInputException: Input length = 1
at java.nio.charset.CoderResult.throwException(CoderResult.java:281)
at org.apache.flume.serialization.ResettableFileInputStream.readChar(ResettableFileInputStream.java:195)
引き続き原因を探っていくと、読み込んでいるファイルに問題があることがわかりました。
Flumeの使用中に遭遇したわけではありませんが、このエラーについて説明したウェブ上の関連記事を紹介します。
結局、問題は解決しなかったので、今後も方法を模索する必要があります。
今日、Java NIOのChannelとBufferを使ってファイル操作をしているときに、次のような報告がありました。
java.nio.charset.MalformedInputException: 入力の長さ = 1
という例外が発生します。
- <スパン java.nio.charset.MalformedInputException: 入力の長さ = 1 <スパン
- at java.nio.charset.CoderResult.throwException(CoderResult.java.CoderResult): 260 )
- at java.nio.charset.CharsetDecoder.decode(CharsetDecoder.java: 781 )
- at cn.fuxi.nio.ReadFile.main(ReadFile.java: 37 )
具体的なJavaのソースコードは以下の通りです。ReadFile.java
- <スパン 公開 クラス ReadFile {
- 公開 静的 ボイド main(String[]アーギュメント) { {
- FileInputStream fis;
- トライ {
- fis = 新しい FileInputStream( "a.txt" );
- FileChannel channel = fis.getChannel();
- // データを繰り返し読み込むためのByteBufferを定義する。
- ByteBuffer byteBuffe = ByteBuffer.allocate() 64 ); // 64バイトを一度に削除する
- // FileChannelからByteBufferにデータを取り込む
- 間 (channel.read(byteBuffe) ! = - 1 <スパン ) {
- // ByteBufferの空白領域をロックする
- byteBuffe.flip()を実行します。
- /* Charsetオブジェクトの作成 */
- Charset charset = Charset.forName()。 GBK" );
- // デコーダを作成する
- CharsetDecoder charsetDecoder = charset.newDecoder()。
- // ByteBufferの中身をトランスコードする
- CharBuffer charBuffer = charsetDecoder.decode(byteBuffe);
- // CharBuffer charBuffer = charset.decode(byteBuffe);
- System.out.println(charBuffer)を実行します。
- // ByteBufferを初期化し、次の読み込みに備えます。
- byteBuffe.clear()を実行します。
- }
- } キャッチ (例外e) {
- // TODO: 例外を処理する
- e.printStackTrace()を実行します。
- }
- }
- }
私が読みたいa.txtファイルの内容は、次のようなシンプルなものです。
- <スパン これは単なるテストです のために ファイルチャンネル
- java.nio.charset.MalformedInputException という例外が報告されることに注意してください。入力長さ 1 一体何が起こっているのか見てみましょう。
で公式のJava APIをチェックアウト。
MalformedInputExceptionは、以下のように記述されています。
入力バイト列が与えられた charset に対して不正である場合、または入力文字列が 16 ビット Unicode の不正な列である場合にスローされるチェックされた例外です。
<スパン
直訳すると、次のような意味です。
このチェック例外は、入力バイト列が与えられた charset に対して不正である場合、または入力文字列が 16-bit Unicode の正規の列でない場合にスローされます。
MalformedInputExceptionが発生するのは、quot;half Chinese problem"のためです。上記の手順を分析すると、CharsetDecoderがByteBufferをデコードする際に、漢字に正常にデコードできることを保証できないため、もしかしたら半分の漢字が含まれている可能性があるからです。この例外は、中国語の文字が半分ある場合に発生します。
<スパン
例として、GBKでは文字が1byte、漢字が2byteなので。
文字列 "我ABC汉字d"が5バイトで傍受された場合は"我ABC"、8バイトで傍受された場合は"我ABC汉字"、ではなく "我ABC汉字?になるはずです。ここで、"? "は漢字の半分であり、これは前方傍受と理解することができます。そのため、例外が報告されます。 (
注)文字コードをGBKからUTF-8に変更した場合、漢字1文字あたりの長さは3文字として計算されます
)
<スパン
<スパン
最初の1枚の解答は
<スパン
<スパン
ByteBuffer byteBuffe = ByteBuffer.allocate(64); の行を ByteBuffer byteBuffe = ByteBuffer.allocate(1024) に置き換えます。
<スパン
<スパン
読みたいa.txtファイルは大きくないので、1024バイトを一気に読むとa.txtファイルの合計サイズより大きくなるので、a.txtファイルを一気に読み込むことにします。だから、もう例外を報告することはない。
<スパン
<スパン
しかし、もし
1024バイトより大きなa.txtファイルを読みたいのですが、やはり例外が吹っ飛ぶ可能性があります。だから、この方法は正しくない。
<スパン
<スパン
<スパン
<スパン
<スパン
私の第二の解答は
<スパン
<スパン
は
CharsetDecoder.decode()メソッドをアウトにして、直接Charset.decode()メソッドを使用します。
<スパン
<スパン
<スパン
これから以下のコードを使用します。
<スパン
<スパン
に変更する。
- <スパン /* Charsetオブジェクトの作成 */
- Charset charset = Charset.forName()。 GBK" );
- // デコーダを作成する
- CharsetDecoder charsetDecoder = charset.newDecoder()。
- // ByteBufferの中身をトランスコードする
- // CharBuffer charBuffer = charsetDecoder.decode(byteBuffe);
<スパン
<スパン
<スパン
<スパン
しかし、このように変更すると、次のような面倒なコードの問題も発生するので、これも勧められない。
- <スパン /* Charsetオブジェクトの作成 */
- Charset charset = Charset.forName()。 GBK" );
- CharBuffer charBuffer = charset.decode(byteBuffe);
しかし、このように変更すると、次のような面倒なコードの問題も発生するので、これも勧められない。
- <スパン これは単なるテストです のために ファイルチャンネル
- java.nio.charset.MalformedInputException という例外が報告されることに注意してください。入力長さ 1 一体何が起こっているのか見てみましょう。
- これは単なるテストです のために ファイルチャンネル
- java.nio.charset.MalformedInputException という例外が報告されることに注意してください。入力長さ 1 底面が見えますか?
- 杵柄ボアの鞘?
どのようにメソッドの具体的な解決策コードを変更するには、今日の心は少し痛い、変更する時間がない、次の変更を掲載する予定です。(あなたは、見てみることができます
http://songjianyong.iteye.com/blog/1399241
をご覧ください)
<スパン
4つ目の方法です。FileChannel.map()メソッドを使用して、すべてのファイルの内容を一度にメモリにマッピングしますが、読み込むファイルが大きすぎる場合、パフォーマンス低下を招きます。コードは以下の通りです。
<スパン
関連
-
mvn' は、内部または外部のコマンド、操作可能なプログラムまたはバッチファイルとして認識されません。
-
が 'X-Frame-Options' を 'sameorigin' に設定したため、フレーム内に存在する。
-
java マイクロソフト払い戻し予期せぬサーバーからのファイルの終了
-
keytool error: java.io.FileNotFoundException: cacerts (アクセス拒否されました。)
-
maven レポート エラー 解決不可能な親POM
-
Javaがリソースリークに遭遇した:'input'が閉じない 解決方法
-
WatchDog + Redisによる分散ロック
-
MyBatisカスタムタイプハンドラ TypeHandler
-
コレクション - PriorityQueueソースコード解析
-
MySQLIntegrityConstraintViolationException、解決方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
スレッド "main "での例外 java.util.NoSuchElementException in Java 問題解決済み
-
アクセス制限です。タイプ 'Application' は API ではない(必要なライブラリに制限がある)。
-
ApplicationContextの起動エラーです。条件レポートを表示するには、アプリケーションを'de'で再実行します。
-
-bash: java: コマンドが見つからない 解決方法
-
SocketException java.netの4つの例外解決策。
-
Junitのユニットテストエラー
-
Zipファイルの圧縮・解凍にantを使用する
-
swagger2 モデルが表示されない モデルが見つからない @ApiModel アノテーションが表示されない問題
-
Java上級(XLVI) ArrayList、Vector、LinkedListの類似点と相違点を簡単に説明できる。
-
javaの継承の基本的な実装