バッファリングされたリーダーから、改行またはリターンキャリッジ(これはreadLine()の機能)でない文字に到達するまで読み込む方法はありますか?BufferedReader - readLine()の代わりにトークンで読み取りますか?
私は行を読んで分割したくないです。改行やキャリッジを無視し、BufferedReaderのパフォーマンスを持つ特定のトークン(タブなど)のみを考慮したいと思います。
バッファリングされたリーダーから、改行またはリターンキャリッジ(これはreadLine()の機能)でない文字に到達するまで読み込む方法はありますか?BufferedReader - readLine()の代わりにトークンで読み取りますか?
私は行を読んで分割したくないです。改行やキャリッジを無視し、BufferedReaderのパフォーマンスを持つ特定のトークン(タブなど)のみを考慮したいと思います。
これはあまり優雅ではありませんが、うまくいく可能性があります。
import java.io.IOException;
import java.io.Reader;
public class MyBufferedReader extends BufferedReader {
/**
*
* @param in
*/
public MyBufferedReader(Reader in) {
super(in);
}
@Override
String readLine(boolean ignoreLF) throws IOException {
StringBuffer s = null;
int startChar;
synchronized (lock) {
ensureOpen();
boolean omitLF = ignoreLF || skipLF;
bufferLoop:
for (;;) {
if (nextChar >= nChars)
fill();
if (nextChar >= nChars) { /* EOF */
if (s != null && s.length() > 0)
return s.toString();
else
return null;
}
boolean eol = false;
char c = 0;
int i;
/* Skip a leftover '\n', if necessary */
if (omitLF && (cb[nextChar] == '\t'))
nextChar++;
skipLF = false;
omitLF = false;
charLoop:
for (i = nextChar; i < nChars; i++) {
c = cb[i];
if (c == '\t') {
eol = true;
break charLoop;
}
}
startChar = nextChar;
nextChar = i;
if (eol) {
String str;
if (s == null) {
str = new String(cb, startChar, i - startChar);
} else {
s.append(cb, startChar, i - startChar);
str = s.toString();
}
nextChar++;
if (c == '\t') {
skipLF = true;
}
return str;
}
if (s == null)
s = new StringBuffer(defaultExpectedLineLength);
s.append(cb, startChar, i - startChar);
}
}
}
}
0をどのように見えるかです:-)ほら(あなたがタブによってつもり分割している)の代わりに
をトンを\します
この
some string some other string
some third string after a newline some forth
and so on
結果のように入力するために、この
MyBufferedReader my = new MyBufferedReader(new InputStreamReader(Main.class.getResourceAsStream("fileWithTabs.txt")));
String line = null;
while((line = my.readLine())!=null) {
System.out.println(line);
}
my.close();
のようにそれを使用することができますが、しかし
some string
some other string
some third string after a newline
some forth
and so on
で非常に非常に厄介な解決策のように見えるので、私は本当にだろう他の巧妙な答えを見たいのですが
確かにそうです。最良の場合には
BufferedReader br = ...
StringBuilder sb = new StringBuilder(ESTIMATED_LENGTH);
int ch;
while ((ch = br.read()) != -1 && ch != '\t') {
sb.append(ch);
}
、あなたは同じくらい良いBufferedReader.readLine()
としてあるパフォーマンスを得ようとしています。最悪の場合、1〜2文字の余分なコピーを実行します(私はそう思います...)。パフォーマンスはそれほど悪くはありません。
BufferedReader
と同じ良好なパフォーマンスを得るには、BufferedReader
コードをハッキングするか、書き直す必要があります。
(親クラスからprivate
メソッドを呼び出しているため、BufferedReader
を拡張しようとしても動作しません)これは許可されていません!メソッドのアクセスを変更することでそれを修正する場合は、 「クローン」BufferedReader
クラスと、それにあなたのメソッドを追加もちろん、あなたのクラスはもはやjava.io.BufferedReader
であるか、そのサブクラス)
1 - 。。正当な理由として、大きな絵を考えます。大量のデータをどこかから読んでいる場合、パフォーマンスのボトルネックはI/Oまたは読んだ後にトークンを使って何をするかのいずれかになりがちです。そうでない場合は、1)java.nio
/CharBuffer
、2)カスタムI/Oスタック、または3)別のプログラミング言語を使用しているはずです。
実際には、ステップ1から4まではBufferedReaderのコピーを使用していて、すべてのプライベート属性とメソッドがprotected(ステップ3)に変更されていることを示しています – Leo
このような場合は、BufferedReaderを使用しないでください。あなただけのキャラクターをしたい場合は、あなたが持つことができる
public String[] splitContentsBy(String split, File file){
try{
byte[] bytes = Files.readAllBytes(file);
String contents = new String(bytes);
String[] array = contents.spilt(split);
}catch(IOException e){
e.printStackTrace();
}
}
:私はそうのようにNIOを使用することになり
char c = '?'; //A question mark, as an example.
String[] parts = splitContentsBy(String.valueOf(c), new File("file.txt");
これは問題を解決しますが、十分な大きさのテキストファイル(例えばサーバーログなど) – Leo
新しい行を無視して、戻るにはちょうどにあなたのreadLine引数を設定します。 文字列のreadLine(真実); タブを検出する条件を実装します。
バッファドリーダーをスキャナでラップすることができます。 – matt