[英]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.Scanner
从java.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"));
由于文件是文本文件,因此从Reader
创建一个BufferedReader
并逐行读取 - 这应该有助于更好地理解它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.