*注意:为了澄清,也许这个问题在InputStream“活着”时并不十分清楚。与telnet气象服务的连接(见下面的链接)保持打开状态。目标是获取来自服务器的所有行。*
从示例Apache WeatherTelnet
code构建,我使用InputStream.read一次输出一个字符的服务器结果(灵感来自javamex tutorial成语),使用chars
方法:
thufir@dur:~$
thufir@dur:~$ java -jar NetBeansProjects/Teln/dist/Teln.jar
------------------------------------------------------------------------------
* Welcome to THE WEATHER UNDERGROUND telnet service! *
------------------------------------------------------------------------------
* *
* National Weather Service information provided by Alden Electronics, Inc. *
* and updated each minute as reports come in over our data feed. *
* *
* **Note: If you cannot get past this opening screen, you must use a *
* different version of the "telnet" program--some of the ones for IBM *
* compatible PC's have a bug that prevents proper connection. *
* *
* comments: jmasters@wunderground.com *
------------------------------------------------------------------------------
Press Return to continue:
^Cthufir@dur:~$
这是所需的输出。但是,使用InputStream
阅读BufferedReader
会导致删除最后一行。 (或者,至少,它没有打印到控制台。)输出错误,使用lines
方法:
thufir@dur:~$
thufir@dur:~$ java -jar NetBeansProjects/Teln/dist/Teln.jar
------------------------------------------------------------------------------
* Welcome to THE WEATHER UNDERGROUND telnet service! *
------------------------------------------------------------------------------
* *
* National Weather Service information provided by Alden Electronics, Inc. *
* and updated each minute as reports come in over our data feed. *
* *
* **Note: If you cannot get past this opening screen, you must use a *
* different version of the "telnet" program--some of the ones for IBM *
* compatible PC's have a bug that prevents proper connection. *
* *
* comments: jmasters@wunderground.com *
------------------------------------------------------------------------------
^Cthufir@dur:~$
thufir@dur:~$
StreamReader
代码:
package teln;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class StreamReader {
private StreamReader() {
}
StreamReader(InputStream inputStream) throws IOException {
lines(inputStream);
}
private void chars(InputStream inputStream) throws IOException {
do {
char ch = (char) inputStream.read();
System.out.print(ch);
} while (true);
}
private void lines(InputStream inputStream) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
String line = "";
do {
System.out.println(line);
} while ((line = br.readLine()) != null);
System.out.println(line);
}
}
据推测,最后一行是“null”?是否可以更改逻辑,以便从lines
开始在chars
内打印最后一行?
答案 0 :(得分:4)
您还没有解释数据的来源,但我怀疑它来自某些来源并且没有关闭流的。< / p>
如果流已关闭 - 例如通过终止连接,如果这是一个客户端/服务器应用程序 - 那么你将看到最后一行。 BufferedReader
肯定会返回最后一行数据,即使它没有以行终止符结束,但只有当知道时它才会到达流的末尾。
答案 1 :(得分:2)
正如Jean所提到的,如果你知道你的输入永远不会以换行'\n'
或回车'\r'
字符结束,那么这就是使用BufferReader的一个缺点。在while
循环后,您可能需要使用ready()
方法来测试最后一行读取后是否确实有更多文本,并使用其中一种read()
方法来提取其余内容文本。或者,将另一个文本阅读器替换为BufferReader。
答案 2 :(得分:2)
BufferedReader#readLine()
读取流,直到它到达\n
,\r
或流的末尾,然后返回它读取的内容或null
。你没有向我们展示一些东西。为什么输出中的行之间有新行?
至于输出结尾处的null
private void lines(InputStream inputStream) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
String line = "";
do {
System.out.println(line); // will print an empty line to start
} while ((line = br.readLine()) != null);
System.out.println(line); // will print null
}
你的循环应该是
while ((line = br.readLine()) != null) {
System.out.println(line);
}
避免打印第一个空的。另外,请勿在{{1}}循环外打印line
。它总是while
,显然(你不会超出null
)。
您的while
方法也会永远循环播放。
您的服务器很可能没有关闭流,因此chars()
所做的基础read
调用不会返回BufferedReader
来指示EOF。你自己杀了这个应用程序吗?
答案 3 :(得分:0)
好的,这就是kludge:
package teln;
import static java.lang.System.out;
import java.io.IOException;
import java.io.InputStream;
public class StreamReader {
private StreamReader() {
}
StreamReader(InputStream inputStream) throws IOException {
printEachLine(inputStream);
}
private void printEachLine(InputStream inputStream) throws IOException {
int foo = 0;
char ch = 0;
StringBuilder sb = new StringBuilder();
out.println("lines..");
boolean isEOL = false; //err, need to set this or get rid of it
do {
foo = inputStream.read();
ch = (char) foo;
//out.print(foo);
sb.append(ch);
if ((ch == 10)) {
out.print(sb);
sb = new StringBuilder();
foo = inputStream.read();
ch = (char) foo;
sb.append(ch);
if (ch != 13) {
while ((255 > ch) && (ch >= 0)) {
sb = new StringBuilder();
foo = inputStream.read();
ch = (char) foo;
sb.append(ch);
out.print(sb);
}
}
sb.append(ch);
}
} while (!isEOL);
}
}
这取决于特定模式后的LF和CR。除非是第一行或最后一行,否则LF,10总是跟随CR,13。因此,在这种特殊情况下,此代码将查找缺少的CR并将其识别为需要特殊输出。
然而,这是一个巨大的假设,可能是特定于这个天气telnet服务。而且,看起来非常脆弱。
现在,我会继续这样做,但会继续寻找另一个答案。