繁体   English   中英

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

[英]Getting meaningful text from Java.io.Reader

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

问题是,他们的方法,称为 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 给出的例子。 这真的很难描述,因为我现在不在我的机器旁,但我认为这是一个编码问题。 这些字符似乎具有类似于报告外观的缩进和结构。 我会在周二回来后立即尝试这些建议(我只是一名实习生,所以我没有为设置远程帐户或其他任何事情而烦恼)。

试试这个:

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的任何子类作为参数,因此保存以使用它。

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

[C@1c8825a5

这只是在Java中的char数组上调用toString的正常输出。 听起来你想将它转换为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 没有 返回 char[]read方法 - 它有一次返回单个字符的方法,或者(更有用的) 接受 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);

它给出了什么毫无意义的字符。 可能是空字符,因为你没有从阅读器中读取所有字符,但最多只读取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();

作为替代方法,您可以使用java.util.Scanner with资源自动关闭阅读器,使用java.util.Scannerjava.io.Reader读取字符串。

这是一个例子:

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

在这种情况下,对scanner.next()的调用将读取所有字符,因为分隔符是文件的结尾。

以下一个班轮也将阅读全文,但不会关闭读者:

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

从 Java 1.8 开始,您可以使用BufferedReader.lines()方法,返回Stream<String>

因此,此代码将返回全部内容,并带有自定义行分隔符“\n”:

String content = new BufferedReader(reader)
    .lines()
    .collect(Collectors.joining("\n"));

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM