Чтение строк и двоичных файлов из одного и того же FileInputStream - PullRequest
7 голосов
/ 20 февраля 2009

У меня есть файл, который содержит некоторое количество простого текста в начале, за которым следует двоичное содержимое в конце. Размер двоичного содержимого определяется какой-то одной из строк обычного текста, которые я прочитал.

Я использовал BufferedReader для чтения отдельных строк, однако он не предоставляет методов для ссылки на чтение байтового массива. readUTF для DataInputStream не читает полностью до конца строки, а метод readLine устарел.

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


private DOTDataInfo parseFile(InputStream stream) throws IOException{
DOTDataInfo info = new DOTDataInfo();
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
int binSize = 0;
String line;
while((line = reader.readLine()) != null){
    if(line.length() == 0)
        break;
    DOTProperty prop = parseProperty(line);
    info.getProperties().add(prop);
    if(prop.getName().equals("ContentSize"))
        binSize = Integer.parseInt(prop.getValue());
}
byte[] content = new byte[binSize];
stream.read(content); //Its all empty now. If I use a DataInputStream instead, its got the values from the file
return info;
}

Ответы [ 7 ]

4 голосов
/ 20 февраля 2009

Вы можете использовать RandomAccessFile. Используйте readLine() для чтения простого текста в начале (обратите внимание на ограничения, как описано в API), а затем readByte() или readFully() для чтения последующих двоичных данных.

Использование базового FileInputStream читать возвращает пустые байтовые массивы.

Это потому, что вы завернули поток в BufferedReader, который, вероятно, использовал все байты из потока при заполнении его буфера.

3 голосов
/ 20 февраля 2009

Если у вас действительно есть файл (а не что-то более сложное для поиска, например, сетевой поток), тогда я предлагаю что-то вроде этого:

  • Открыть файл как FileInputStream
  • Оберните его в InputStreamReader и BufferedReader
  • Прочитайте текст, чтобы узнать, сколько там контента
  • Закрыть BufferedReader (который закроет InputStreamReader, который закроет FileInputStream)
  • Открыть файл
  • Перейти к (общая длина файла - длина двоичного содержимого)
  • Прочитать остальные данные как обычно

Вы можете просто вызвать mark() в начале FileInputStream, а затем reset() и skip(), чтобы добраться до нужного места, если вы хотите избежать повторного открытия файла. (Я искал InputStream.seek(), но я не вижу его - я не помню, чтобы хотел его раньше в Java, но разве у него его нет? Ick.)

2 голосов
/ 20 февраля 2009

Вам необходимо использовать InputStream. Читатели для символьных данных. Посмотрите, как обернуть ваш входной поток в DataInputStream, например:

stream=new DataInputStream(new BufferedInputStream(new FileInputStream(...)));

Поток ввода данных даст вам много полезных методов для чтения различных типов данных и, конечно, базовые методы InputStream для чтения байтов.

(Это именно то, что должен сделать HTTP-сервер, чтобы прочитать запрос с содержимым.)


readUTF не читает строку, он читает строку, которая была написана в (измененном) формате UTF8 - см. JavaDoc.

1 голос
/ 31 июля 2009

Увы, DataInputStream устарела и не обрабатывает UTF. Но это должно помочь (он читает строку из двоичного потока без какой-либо информации).

public static String lineFrom(InputStream in) throws IOException {
    byte[] buf = new byte[128];
    int pos = 0;
    for (;;) {
        int ch = in.read();
        if (ch == '\n' || ch < 0) break;
        buf[pos++] = (byte) ch;
        if (pos == buf.length) buf = Arrays.copyOf(buf, pos + 128);
    }
    return new String(Arrays.copyOf(buf, pos), "UTF-8");
}
0 голосов
/ 20 февраля 2009

Я рекомендую использовать DataInputStream . У вас есть следующие варианты:

  • Чтение как текстового, так и двоичного содержимого с помощью DataInputStream
  • Откройте BufferedReader, прочитайте текст и закройте поток. Затем откройте DataInputStream, пропустите байты, равные размеру текста, и прочитайте двоичные данные.
0 голосов
/ 20 февраля 2009

Вы можете прочитать текст с BufferedReader. Когда вы знаете, где начинается двоичный файл, вы можете закрыть файл и открыть его с помощью RandomAccessFile и прочитать двоичный файл из любой точки файла. Или вы можете прочитать файл как двоичный файл и преобразовать в текст разделы, которые вы идентифицируете как текст. {Использование новой строки (байты, кодировка)}

0 голосов
/ 20 февраля 2009

Правильный способ - использовать InputStream некоторой формы, возможно, FileInputStream, если это не станет барьером производительности.

Что вы имеете в виду «Использование базового FileInputStream для чтения возвращает пустые байтовые массивы.»? Это кажется маловероятным и, вероятно, в этом ваша ошибка. Можете ли вы показать нам пример кода, который вы пробовали?

...