Java の代入は演算子なので値を持ち、それは代入された値となります。例えば、
java
1int a;
2int b = (a = 2 + 3) * 4;
を実行すると、まず括弧の中の a = 2 + 3 が評価されて a = 5 となり、次に括弧の中の値は代入された値 5 なので、b = 5 * 4 が評価されて b = 20 になります。
問題の while 文ですが、
java
1while (0 <= (line = reader.read(b))) {
2 sb.append(b, 0, line);
3}
まず、括弧の中の line = reader.read(b) が実行されます。read メソッド は reader から文字を配列 b に読み込み、読み込んだ文字数を返すので、それが変数 line に格納されます。
そして、括弧の中の値は代入された値なので、条件 0 <= line が成り立てばループを継続します。(read メソッドはストリームの終わりに達した場合は -1 を返すので、そこでループから抜けます。)
ループの中では append メソッド によって配列 b の先頭から line 文字分、つまり今回読み込まれた文字が sb に追加されます。
ここで重要なのは、ループの継続条件をチェックする際には、毎回 line = reader.read(b) が実行されるということです。これを次のようにループの外に出してしまうと、line の値はループ中は変化しないため、無限ループになる可能性があります。
java
1int line = reader.read(b);
2while (0 <= line) {
3 sb.append(b, 0, line);
4}
ループの条件の中で代入を行わないようにするには、while の最後にもう一度読み込みを行うか、
java
1int line = reader.read(b);
2while (0 <= line) {
3 sb.append(b, 0, line);
4 line = reader.read(b);
5}
同じことを何度も書きたくない場合は、次のように書く必要があります。
java
1while (true) {
2 int line = reader.read(b);
3 if (!(0 <= line)) { // または if (line < 0) {
4 break;
5 }
6 sb.append(b, 0, line);
7}