web-dev-qa-db-ja.com

Javaスキャナーがファイル全体を通過しない

私はJavaでプログラムを書いています、そして私がする必要があることの1つは、最短経路問題のためにすべての有効な場所のセットを作成することです。場所は.txtで定義されています厳密なパターン(1行に1つのエントリ、余分な空白なし)に従い、.nextLineを使用してデータを取得するのに最適なファイル。私の問題は、ファイルへの241行(432行中)でスキャナーが3/4の動作を停止することです。エントリを通過する途中で、新しい行を認識しません。

私のコード:

    //initialize state space
private static Set<String> posible(String posLoc) throws FileNotFoundException {
    Scanner s = new Scanner(new File(posLoc));
    Set<String> result = new TreeSet<String>();
    String availalbe;
    while(s.hasNextLine()) {
        availalbe = s.nextLine();
        result.add(availalbe);
    }
    s.close();
    return result;
}

データ

Shenlong Gundam
Altron Gundam
Tallgee[scanner stops reading here]se
Tallgeese II
Leo (Ground)
Leo (Space)

もちろん、「スキャナーがここで読み取りを停止する」はデータに含まれていません。スキャナーがファイルの読み取りを停止する場所をマークしているだけです。これはファイルの3068バイトですが、同じプログラムでほぼ同じコードを使用して、パスをエンコードする261行の14KB .txtファイルを読み取っているため、何の影響もありません。どんな助けでもいただければ幸いです。

ありがとうございました。

17
Fizzmaister

スキャナーがファイルを読み取る際に問題がありますが、それが何であるかわかりません。おそらくファンキーな文字列エンコーディングが原因で、ファイルの終わりに到達していないのに、ファイルの終わりに到達したと誤って信じています。代わりに、FileReaderオブジェクトをラップするBufferedReaderオブジェクトを使用してみてください。

例えば。、

   private static Set<String> posible2(String posLoc) {
      Set<String> result = new TreeSet<String>();
      BufferedReader br = null;
      try {
         br = new BufferedReader(new FileReader(new File(posLoc)));
         String availalbe;
         while((availalbe = br.readLine()) != null) {
             result.add(availalbe);            
         }
      } catch (FileNotFoundException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      } finally {
         if (br != null) {
            try {
               br.close();
            } catch (IOException e) {
               e.printStackTrace();
            }
         }
      }
      return result;
  }

編集
私はあなたの問題を最小限に抑えようとしました、そしてこれだけで問題を引き出すのに十分でした:

   public static void main(String[] args) {
      try {
         Scanner scanner = new Scanner(new File(FILE_POS));
         int count = 0;
         while (scanner.hasNextLine()) {
            String line = scanner.nextLine();
            System.out.printf("%3d: %s %n", count, line );
            count++;
         }

私はprintfでScannerオブジェクトをチェックしました:

System.out.printf("Str: %-35s size%5d; Has next line? %b%n", availalbe, result.size(), s.hasNextLine());

そして、ファイルが終了したと考えていることを示しました。問題の原因となった行を確認するために、データからファイルへの行を段階的に削除する過程にありましたが、それはあなたに任せます。

私は同じ問題に遭遇しました、そしてこれは私がそれを修正するためにしたことです:

1.Saved the file I was reading from into UTF-8
2.Created new Scanner like below, specifying the encoding type:


   Scanner scanner = new Scanner(new File("C:/IDSBRIEF/GuidData/"+sFileName),"UTF-8");   
7
Learner123

私も同じ問題を抱えていました。スキャナーはファイルの最後まで読み取らず、実際にはWordの途中で停止します。スキャナーに制限を設定するのは問題だと思いましたが、rfeakからの文字エンコードに関するコメントに注目しました。

.txtに読み込んでいたUTF-8を再保存しましたが、問題は解決しました。メモ帳がデフォルトでANSIに設定されていたことが判明しました。

5
The Aa of Ron

私の場合:

  • 私のメインプログラム(A)では、41021バイトのファイルから常に16384バイトを読み取ります。停止する文字は、通常の印刷可能なテキストの行の途中にあります
  • スキャナーと印刷行だけで小さな別のプログラム(B)を作成すると、ファイル全体が読み取られます
  • (A)で「UTF-8」を指定しても16384を読み取ります
  • (A)で「ASCII」を指定しても16384を読み取ります
  • (A)で「Cp1252」を指定すると、ファイル全体が読み取られます
  • 私の入力txtファイルはユーザーによって送信され、ユーザーが特定のエンコーディングでそれらを書き込むかどうかはわかりません

結論

  • スキャナーはファイルをブロックごとに読み取り、正しく読み取られたデータを戻り文字列に書き込むようですが、予期したものとは異なるエンコーディングのブロックを見つけると、終了しますサイレント(痛い)そして戻ります部分文字列
  • 読み取ろうとしているtxtファイルはCp1252、(A)ソースファイルはUTF-8、(B)ソースファイルはCp1252であるため、(B)はエンコードを指定せずに機能しました

解決

  • スキャナーを忘れて使用する

String fullFileContents = new String(Files.readAllBytes(myFile.toPath()));

もちろん、ASCII以外の文字は、エンコーディングがわからないため、このように確実に読み取ることはできませんが、ASCII文字は確実に読み取られます。ファイル内のASCII文字のみが必要で、ASCII以外の部分を破棄できる場合に使用します。

1
golimar

Csvファイルでも同じ問題が発生しました。Windowsでは機能しましたが、Linuxでは機能しませんでした。

Nodepad ++でファイルを開き、エンコードを変更し、次を選択します:UTF8でエンコード(BOMを使用)。私の場合は問題を解決しました

0
anakin59490

スキャナーが862行目で読み取りを停止したtxtファイルがありましたが、これは奇妙な問題でした。私がしたことは、別のファイルを作成することでした(問題を再現しようとするため)。最初に862行未満を追加し、次に862を超えて追加しましたが、正常に機能しました。

したがって、問題は、以前のファイルの862行目に、スキャナーが早期に読み取りを終了するように誤解させる可能性のある文字や記号などの問題があったことだと思います。

結論:この経験に基づいて、スキャナーが読み取りを停止する正確な行を見つけて、ある種の問題の解決策を見つけることをお勧めします。

0
evaldeslacasa

Linuxサーバーでも同様の問題が発生し、最終的に以下のコードが機能しました。

スキャナーscanner = new Scanner(new File(filename)、 "UTF-8");

0
user8373873