2017-12-21 16 views
0

このコードを使用してファイルを実行すると、最初は正常に動作しますが、 ですが、2番目の実行(同じファイル上)ではFiles.readAllLinesが例外をスローします。MalformedInputException:2回以上実行した場合の入力の長さ= 1

すべてのコードは(各ファイルについてですが、この場合は単なるものです) ファイルからすべての行を取得して削除してから、同じ内容で再充填します。

for (File file : content) { 
    List<String> fillLines = new ArrayList<>(); 
    try { 
     fillLines = Files.readAllLines(file.toPath()); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    if (fillLines.size() > 0) { 
     file.delete(); 
     FileWriter fileWriter = new FileWriter(file, false); 

     for (String line : fillLines) { 
      fileWriter.write(line); 
      if (fillLines.indexOf(line) < fillLines.size() - 1) 
       fileWriter.append(System.lineSeparator()); 
     } 
     fileWriter.close(); 
    } 
} 

fileWriter.append(System.lineSeparator());のためでしょうか?

他のすべてのQuestioneerは、間違った文字セットで読むことで初めて失敗しました。しかし、私は一度それを実行することができるように、私は読んでいないが間違って何かを書いているので、charsetを変更することは避けることができる回避策のようです。

スタックトレース:

java.nio.charset.MalformedInputException: Input length = 1 
    at java.nio.charset.CoderResult.throwException(Unknown Source) 
    at sun.nio.cs.StreamDecoder.implRead(Unknown Source) 
    at sun.nio.cs.StreamDecoder.read(Unknown Source) 
    at java.io.InputStreamReader.read(Unknown Source) 
    at java.io.BufferedReader.fill(Unknown Source) 
    at java.io.BufferedReader.readLine(Unknown Source) 
    at java.io.BufferedReader.readLine(Unknown Source) 
    at java.nio.file.Files.readAllLines(Unknown Source) 
    at java.nio.file.Files.readAllLines(Unknown Source) 

ここで、以下のものがFiles.readAllLines()のドキュメントから

fillLines = Files.readAllLines(file.toPath()); 
+0

'このコードのファイル上で実行すると、うまく最初の時間を動作しますが、セカンドランで、Files.readAllLinesはException'を言っスロー - セカンドランで、あなたは、同じファイル名の第二の試みを意味しますか、またはループ内の2番目のファイル名。おそらく、2番目のファイルに問題があります。 – Eran

+0

同じファイル上でプログラムを2回実行する – SlaxX

+0

'fillLines.indexOf'は厄介です。あなたは索引ごとに行を反復しようとしましたか?また、例外を投稿することはできますか? – daniu

答えて

2

を指す:ファイルから

バイトはUTF-8を使用して文字にデコードされ、文字セット

FileWriterのドキュメントから:このクラスのコンストラクタ

デフォルトの文字エンコーディングとデフォルトのバイトバッファサイズが許容されていることを前提としています。これらの値を自分で指定するには、FileOutputStreamでOutputStreamWriterを構築します。

したがって、デフォルトのプラットフォームエンコーディング(あなたの場合はUTF8ではありません)とUTF8で読むことができます。これが例外の原因です。書き込みと読み取りには同じエンコーディングを使用します。上記のドキュメントでは、UTF8エンコーディングを記述する方法を説明しています。

+0

これまでのところ、ISO_8859_1で動作するようです。 – SlaxX

+0

これはすべてのOSとすべてのファイル世界中のすべてのコンピュータでテキストのように読む? – SlaxX

+0

いいえ、誤ったエンコーディングを使用してファイルを読むと、不正な文字が読み込まれたり、例外がスローされたりします。しかし、あなたはそのファイルの所有者であるようです(あなたが削除して書き込むので、サポートしているすべての文字/言語をサポートするエンコーディングを選択する必要があります)。 UTF8は良い選択です。 ISO_8859_1はそうではありません:256文字しかサポートしていません。 –

0
for (File file : content) { 
    Path path = fiel.toPath(); 
    List<String> fillLines; 
    try { 
     fillLines = Files.readAllLines(path); 
    } catch (IOException e) { 
     System.err.println("Error while reading " + path); 
     e.printStackTrace(); 
     fillLines = new ArrayList<>(); 
    } 

    if (!fillLines.isEmpty()) { 
     //Files.delete(path); 
     // See -A- 
     Files.write(path, fillLines, StandardOpenOptions.TRUNCATE_EXISTING); 
    } 
} 

なぜ、これが短くて安全で安定しているのでしょうか?

エラー

あなたは、読み出し用及び書き込み用の文字セットを示すものではありません。

Files前に、これは、プラットフォームのエンコーディングを使用し、オーバーロードコンストラクタは文字集合/文字エンコーディングでが存在することを意味します。

また、非常に古いFileReader/FileWriterの場合でも、過負荷は存在しません。常にプラットフォームコード-を使用します。

FilesとUnicodeのUTF-8がデフォルトになりました。java文字列にはUnicodeが含まれているため、変換はロスレスになります。 素晴らしい!

しかし、UTF-8は、8ビット目が有効マルチバイトシーケンスを実現するために特に使用されている必要がありますとしてWindows-1252のようなものを書いた後、UTF-8で読んだことはおそらく、失敗します。

注:もともとはファイルがUTF-8であったが、一度書き込まれると、もはや有効ではない(有効なUTF-8ではない)。

// -A- 
// Possibly add a BOM (begin of file marker) to identify to Windows 
// that this file is in UTF-8 (works for UTF-16 too). 
// This is primarily for Notepad. A BOM is redundant, invisible (zero width space) 
// and generally inadvisable if not needed. 
if (!lines.get(0).startsWith("\uFEFF")) { 
    lines.set(0, "\uFEFF" + lines.get(0)); 
} 
関連する問題