从Java.io.Reader获取有意义的文本

时间:2011-12-30 20:47:42

标签: java java-io

我正在编写一个程序,我正在使用其他公司的图书馆从他们的网站下载一些报告。我想在将这些报告写入文件之前解析这些报告,因为如果它们符合某些条件,我想忽略它们。

问题是,他们的方法叫做download(),返回一个java.io.Reader。唯一可用的方法是

int read(char[] cbuf);

打印出这个返回的数组会给我带来无意义的字符。我想能够识别我正在使用的字符集或将其转换为字节数组,但我无法弄清楚如何做到这一点。我试过了

//retrievedFile is my Reader object
char[] cbuf = new char[2048];
int numChars = retrievedFile.read(cbuf);
//I've tried other character sets, too
new String(cbuf).getBytes("UTF-8");

我害怕转向更有用的读者,因为我无法确定它是否会起作用。有什么建议吗?

修改

当我说它打印出“无意义的人物”时,我并不是说它看起来像Jon Skeet给出的例子。这很难描述,因为我现在不在我的机器上,但我认为这是一个编码问题。字符似乎具有与报告外观类似的缩进和结构。我星期二回来后会立即尝试这些建议(我只是一名实习生,所以我没有费心设置远程帐户或其他任何东西)。

6 个答案:

答案 0 :(得分:15)

试试这个:

BufferedReader in = new BufferedReader(retrievedFile);
String line = null;
StringBuilder rslt = new StringBuilder();
while ((line = in.readLine()) != null) {
    rslt.append(line);
}
System.out.println(rslt.toString());

不要将Reader强制转换为任何类,因为您不知道它的真实类型。 而是使用BufferedReader并将Reader传递给它。 BufferedReader将java.io.Reader的任何子类作为参数,因此保存即可使用它。

答案 1 :(得分:4)

打印char[]本身可能会给你类似的东西:

[C@1c8825a5

这只是在Java中toString数组上调用char的正常输出。听起来你想将它转换为String,你可以使用String(char[])构造函数。这是一些示例代码:

public class Test {
    public static void main(String[] args) {
        char[] chars = "hello".toCharArray();
        System.out.println((Object) chars);

        String text = new String(chars);
        System.out.println(text);
    }
}

另一方面,java.io.Reader 没有read方法返回 a char[] - 它有方法要么一次返回一个字符,要么(更有用的)接受一个char[]来填充数据,并返回读取的数据量。这实际上是您的示例代码所显示的内容。您只需要使用char数组和读取的字符数来创建新的String。例如:

char[] buffer = new char[4096];
int charsRead = reader.read(buffer);
String text = new String(buffer, 0, charsRead);

但请注意,它可能无法一次性返回所有数据。您可以使用BufferedReader逐行读取它,或循环以获取所有信息。 Guava在其CharStreams类中包含有用的代码。例如:

String allText = CharStreams.toString(reader);

List<String> lines = CharStreams.readLines(reader);

答案 2 :(得分:1)

它给出了什么毫无意义的字符。可能是空字符,因为你没有从阅读器中读取所有字符,但最多只读取2048个字符,你忽略了read方法返回的值(它告诉你实际读取了多少个字符。

如果要将整个事物读入String,则必须循环直到返回值为负,并将每次迭代时读取的字符(从0到numChars)附加到StringBuilder。

StringBuilder builder = new StringBuilder();
int numChars;
while ((numChars = reader.read(cbuf)) >= 0) {
    builder.append(cbuf, 0, numChars);
}
String s = builder.toString();

答案 3 :(得分:0)

将它包装在更有用的东西中,比如StringReader或BufferedReader:

http://docs.oracle.com/javase/6/docs/api/

答案 4 :(得分:0)

由于该文件是文本文件,因此请从BufferedReader创建Reader并逐行阅读 - 这应该有助于更好地理解它。

答案 5 :(得分:0)

As an alternative you can read a string from a java.io.Reader using java.util.Scanner using try with resources which should automatically close the reader.

Here is an example:

Reader in = ...
try (Scanner scanner = new Scanner(in).useDelimiter("\\Z")) {
    String text = scanner.next();
    ... // Do something with text
}

In this situation the call to scanner.next() will read all characters, because the delimiter is the end of file.

The following one liner will also read the whole text but will not close the reader:

String text = new Scanner(in).useDelimiter("\\Z").next();