Получение значимого текста из Java.io.Reader - PullRequest
4 голосов
/ 31 декабря 2011

У меня есть программа, которую я пишу, где я использую библиотеку другой компании для загрузки некоторых отчетов с их веб-сайта.Я хочу проанализировать эти отчеты перед тем, как записать их в файл, потому что, если они соответствуют определенным критериям, я хочу игнорировать их.

Проблема в том, что их метод, называемый 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");

и боюсь опускаться до более полезного читателя, потому что я не могу точно знать, сработает он или нет.Любые предложения?

РЕДАКТИРОВАТЬ

Когда я говорю, что это печатает "бессмысленные символы", я не имею в виду, что это похоже на пример, приведенный Джоном Скитом.Это действительно сложно описать, потому что я сейчас не на своей машине, но я думаю, что это проблема кодирования.Кажется, что символы имеют отступы и структуру, похожую на внешний вид отчетов.Я попробую эти предложения, как только вернусь во вторник (я только стажер, поэтому я не удосужился настроить удаленную учетную запись или что-либо еще).

Ответы [ 6 ]

15 голосов
/ 31 декабря 2011

Попробуйте:

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 в качестве аргумента, поэтому его можно сохранить.

4 голосов
/ 31 декабря 2011

Распечатка самого char[], вероятно, даст вам что-то вроде:

[C@1c8825a5

Это обычный вывод вызова toString для массива char в Java.Похоже, вы хотите преобразовать его в 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[] - этоесть методы, которые либо возвращают один символ за раз, либо (более полезно) принимают a 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);
1 голос
/ 31 декабря 2011

Какие бессмысленные символы он дает.Вероятно, нулевые символы, потому что вы не читаете все символы из читателя, но самое большее 2048 символов, и игнорируете возвращаемое значение из метода read (который говорит вам, сколько символов было фактически прочитано.

Если вы хотите прочитать все это в строку, вам нужно будет выполнить цикл до тех пор, пока возвращаемое значение не станет отрицательным, и добавить символы, прочитанные на каждой итерации (от 0 до numChars), в StringBuilder.

StringBuilder builder = new StringBuilder();
int numChars;
while ((numChars = reader.read(cbuf)) >= 0) {
    builder.append(cbuf, 0, numChars);
}
String s = builder.toString();
0 голосов
/ 13 ноября 2018

В качестве альтернативы вы можете прочитать строку из java.io.Reader, используя java.util.Scanner, используя try с ресурсами, которые должны автоматически закрывать читатель.

Вот пример:

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();
0 голосов
/ 31 декабря 2011

Поскольку файл является текстовым файлом, создайте BufferedReader из вашего Reader и читайте его построчно - это должно помочь понять его больше.

0 голосов
/ 31 декабря 2011

Оберните это во что-нибудь более полезное, например, StringReader или BufferedReader:

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

.

...