BufferedReader の readLine() メソッドはブロッキングです。ストリームの最後に到達すると null を返します。ただし、クライアントのソケットが閉じる前に破棄された場合は IO 例外が発生します。通常はソケットを使用する方法です。不要な場合は close() を使用してソケットを閉じます。
複数行のファイルから各行を順番に読み込み、処理後に出力します。次の方法を使用すると、行の最初の文字が最初の行を除いて失われます。
文字列 str = null;
br=new BufferedReader(new FileReader(fileName));
do{
str = buf.readLine( ));
}while(br.read()!=-1);
次の使用法では、各行の最初の文字が少なくなります。 < a i=7> while(br.read() != -1){ str = br.readLine(); } < /span> 理由は br.read() != -1 の判定条件にあります。なぜなら、この条件を実行すると、実際には文字を読み取っているのですが、読み込んだ文字はここでは処理されないので、1文字少なくなってしまいます。他の行と 1 行減ります!
次のメソッドを使用することをお勧めします
String str = null;
while((str = br.readLine()) != null ){ a> }
//System.out.println(str);//この時点で、str は string の行を保存します
これにより、文字を失わずに行を取得できるようになります。
IO を記述するプログラムはそれほど多くありませんが、次の理由で BufferedReader/BufferedInputStream を何度か使用しました。
它有一个很特别的方法:readLine(),使用起来特别方便,每次读回来的都是一行,省了很多手动拼接buffer的琐碎;
它比较高效,相对于一个字符/字节地读取、转换、返回来说,它有一个缓冲区,读满缓冲区才返回;一般情况下,都建议使用它们把其它Reader/InputStream包起来,使得读取数据更高效。
对于文件来说,经常遇到一行一行的,特别相符情景。
今回の Bluetooth 開発では、相互にデータを送信するために 2 つの Bluetooth が使用されました (つまり、1 つは送信、もう 1 つは受信)。オープン ソース コンポーネントである Bluecove は、すべてのデータ読み取りを InputStream にカプセル化しました。これは、通常の IO 読み取りと同等です。とても便利なので当然readLine()を使います。
データを送る:
[Java] プレーンコピーを表示する
BufferedWriter output = new BufferedWriter(new OutputStreamWriter(conn.openOutputStream()));
int i = 1;
String message = "message " + i;
while(isRunning) {
output.write(message+"/n");
i++;
}
データの読み取り:
[Java] プレーンコピーを表示する
BufferedReader input = new BufferedReader(new InputStreamReader(m_conn.openInputStream()));
String message = "";
String line = null;
while((line = m_input.readLine()) != null) {
message += line;
}
System.out.println(message);
上記はコードの抜粋ですが、このコードを使用すると、データの書き込みは毎回成功しますが、読み取り側では(ストリームがオフになっていない限り)データが出力されないことがわかります。苦労した結果、理解する必要のある大きな問題がいくつかあることがわかりました。
误以为readLine()是读取到没有数据时就返回null(因为其它read方法当读到没有数据时返回-1),而实际上readLine()是一个阻塞函数,当没有数据读取时,就一直会阻塞在那,而不是返回null;因为readLine()阻塞后,System.out.println(message)这句根本就不会执行到,所以在接收端就不会有东西输出。要想执行到System.out.println(message),一个办法是发送完数据后就关掉流,这样readLine()结束阻塞状态,而能够得到正确的结果,但显然不能传一行就关一次数据流;另外一个办法是把System.out.println(message)放到while循环体内就可以。
readLine()只有在数据流发生异常或者另一端被close()掉时,才会返回null值。
如果不指定buffer大小,则readLine()使用的buffer有8192个字符。在达到buffer大小之前,只有遇到"/r"、"/n"、"/r/n"才会返回。
readLine() の本質 (以下は JDK ソース コードから抜粋):
[Java] プレーンコピーを表示する
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;
}
......//其它
}
private void fill() throws IOException {
..../其它
int n;
do {
n = in.read(cb, dst, cb.length - dst); //实质
} while (n == 0);
if (n > 0) {
nChars = dst + n;
nextChar = dst;
}
}
上記からわかるように、readLine() は、read(char[] cbuf, int off, int len) を呼び出してデータを読み取り、「/r」または「/n」に基づいてデータ処理を実行します。
Java I/O の本にも次のように書かれています。
public String readLine() throws IOException
このメソッドは、テキスト ファイルからのテキスト行を含む文字列を返します。 /r、/n、および /r/n は改行とみなされ、返される文字列には含まれません。このメソッドは、System.in からユーザー入力を読み取るときによく使用されます。これは、ほとんどのプラットフォームでは、ユーザーが全行を入力した後 (つまり、Return キーを押した後) にのみユーザーの入力が実行中のプログラムに送信されるためです。
readLine() には、DataInputStream の readLine() メソッドと同じ行末の問題があります。つまり、ストリームを終了する単一の復帰でハングする可能性があります。この問題はネットワーク接続で特に深刻であり、readLine() は決して使用すべきではありません。
要約すると、readLine() を使用する場合は、次の点に注意する必要があります。
读入的数据要注意有/r或/n或/r/n
没有数据时会阻塞,在数据流异常或断开时才会返回null
使用socket之类的数据流时,要避免使用readLine(),以免为了等待一个换行/回车符而一直阻塞
昔勉強していたときはあまり気にしていなかったので、プロジェクトで使ってみて初めて知りました(笑)
1. txtファイルの読み込み方法は色々ありますが、今回は(便宜上)文字ストリームを使って読み込みました。
FileReader fr = new FileReader(“f:\TestJava.java”);
BufferedReader bf = new BufferedReader(fr);
//ここを読んでください
int b;
while((b=bf.read())!=-1){
System.out.println(bf.readLine());
}
は、各行の最初の文字が表示されていないことを検出しました。理由: b=bf.read())!=-1 は毎回最初に 1 バイトを読み取るため、後続の bf.readLine ());
1 行あたり 1 バイト少なく読み取られます
したがって、使用する必要があります
文字列値String = null;
while ((valueString=bf.readLine())!=null){
System.out.println(valueString);
}