13

BufferedReaderを介してファイルを読み取っています

String filename = ...
br = new BufferedReader( new FileInputStream(filename));
while (true) {
   String s = br.readLine();
   if (s == null) break;
   ...
}

行が「\n」または「\r\ n」で区切られているかどうかを知る必要があります。それを見つける方法はありますか?

FileInputStreamを開きたくないので、最初にスキャンします。理想的には、BufferedReaderは知っている必要があるので、聞いてみたいと思います。

BufferedReaderをオーバーライドしてハッキングできてうれしいですが、ファイルストリームを2回開きたくありません。

ありがとう、

注:ファイルは別のオペレーティングシステム上の別のアプリによって書き込まれた可能性があるため、現在の行区切り記号(System.getProperty( "line.separator")によって返される)は使用できません。

4

9 に答える 9

14

BufferedReaderクラスと同相にするには、\ n、\ r、\ n \ r、および\ r\nのエンドラインセパレーターを処理する次のメソッドを使用できます。

public static String retrieveLineSeparator(File file) throws IOException {
    char current;
    String lineSeparator = "";
    FileInputStream fis = new FileInputStream(file);
    try {
        while (fis.available() > 0) {
            current = (char) fis.read();
            if ((current == '\n') || (current == '\r')) {
                lineSeparator += current;
                if (fis.available() > 0) {
                    char next = (char) fis.read();
                    if ((next != current)
                            && ((next == '\r') || (next == '\n'))) {
                        lineSeparator += next;
                    }
                }
                return lineSeparator;
            }
        }
    } finally {
        if (fis!=null) {
            fis.close();
        }
    }
    return null;
}
于 2012-12-11T20:32:10.380 に答える
7

javaドキュメント(私はpythonistaであることを告白します)を読んだ後、特定のファイルで使用されている行末エンコーディングを決定するための明確な方法がないようです。

私がお勧めできる最善のことはBufferedReader.read()、ファイル内のすべての文字を使用して反復することです。このようなもの:

String filename = ...
br = new BufferedReader( new FileInputStream(filename));
while (true) {
   String l = "";
   Char c = " ";
   while (true){
        c = br.read();
        if not c == "\n"{
            // do stuff, not sure what you want with the endl encoding
            // break to return endl-free line
        }
        if not c == "\r"{
            // do stuff, not sure what you want with the endl encoding
            // break to return endl-free line
            Char ctwo = ' '
            ctwo = br.read();
            if ctwo == "\n"{
                // do extra stuff since you know that you've got a \r\n
            }
        }
        else{
            l = l + c;
        }
   if (l == null) break;
   ...
   l = "";
}
于 2011-05-24T16:43:07.183 に答える
3

BufferedReader.readLine()改行が何であったかを判断する手段を提供しません。知る必要がある場合は、自分で文字を読んで、自分で改行を見つける必要があります。

Guavaの内部LineBufferクラス(およびそれが使用されているパブリックLineReaderクラス)に興味があるかもしれません。は改行文字であるコールバックメソッドを提供します。あなたはおそらくそれに基づいてあなたがやりたいことをするために何かをベースにすることができます。APIは、行のテキストと行の終わりの両方を含むオブジェクトがどこにあるかのように見える場合があります。LineBuffervoid handleLine(String line, String end)endpublic Line readLine()Line

于 2011-05-24T16:30:18.800 に答える
2

BufferedReader受け入れないFileInputStreams

いいえ、BufferedReaderによって読み取られているファイルで使用されたラインターミネータ文字を見つけることはできません。その情報は、ファイルの読み取り中に失われます。

残念ながら、以下のすべての回答は正しくありません。

編集:はい、いつでもBufferedReaderを拡張して、必要な追加機能を含めることができます。

于 2011-05-24T16:23:10.670 に答える
2

答えは次のようになります。行末が何であったかがわかりません。

同じ関数で行末を引き起こす原因を探しています。BufferedReaderのソースコードを見た後、BufferedReader.readLineが「\r」または「\n」の行を終了し、残りの「\r」または「\n」をスキップすることを確認できます。ハードコードされており、設定は関係ありません。

于 2012-07-20T11:29:30.227 に答える
1

このファイルをSwingテキストコンポーネントに読み込んでいる場合は、JTextComponent.read(...)メソッドを使用してファイルをドキュメントに読み込むことができます。次に、次を使用できます。

textComponent.getDocument().getProperty( DefaultEditorKit.EndOfLineStringProperty );

ファイルで使用された実際のEOL文字列を取得します。

于 2011-05-24T16:38:58.053 に答える
1

多分あなたはScanner代わりに使うことができます。

に正規表現を渡してScanner#useDelimiter()、カスタム区切り文字を設定できます。

String regex="(\r)?\n";
String filename=....;
Scanner scan = new Scanner(new FileInputStream(filename));
scan.useDelimiter(Pattern.compile(regex));
while (scan.hasNext()) {
    String str= scan.next();
    // todo
}

以下のコードを使用して、に変換できBufferedReaderますScanner

 new Scanner(bufferedReader);
于 2020-04-29T06:16:16.697 に答える
0

役に立つかどうかはわかりませんが、ファイルをかなり先に読んだ後で、行区切り文字を見つける必要がある場合があります。

この場合、私はこのコードを使用します:

/**
* <h1> Identify which line delimiter is used in a string </h1>
*
* This is useful when processing files that were created on different operating systems.
*
* @param str - the string with the mystery line delimiter.
* @return  the line delimiter for windows, {@code \r\n}, <br>
*           unix/linux {@code \n} or legacy mac {@code \r} <br>
*           if none can be identified, it falls back to unix {@code \n}
*/
public static String identifyLineDelimiter(String str) {
    if (str.matches("(?s).*(\\r\\n).*")) {     //Windows //$NON-NLS-1$
        return "\r\n"; //$NON-NLS-1$
    } else if (str.matches("(?s).*(\\n).*")) { //Unix/Linux //$NON-NLS-1$
        return "\n"; //$NON-NLS-1$
    } else if (str.matches("(?s).*(\\r).*")) { //Legacy mac os 9. Newer OS X use \n //$NON-NLS-1$
        return "\r"; //$NON-NLS-1$
    } else {
        return "\n";  //fallback onto '\n' if nothing matches. //$NON-NLS-1$
    }
}
于 2014-07-22T14:37:14.027 に答える
-2

groovyを使用している場合は、次のようにすることができます。

def lineSeparator = new File('path/to/file').text.contains('\r\n') ? '\r\n' : '\n'
于 2014-06-02T15:39:59.877 に答える