Странное поведение FileInputStream / DataFileInputStream: поиск () в нечетных позициях - PullRequest
2 голосов
/ 19 октября 2010

Товар:

Итак, у меня есть этот файл двоичных данных (размер - ровно 640631 байт), и я пытаюсь заставить его читать Java.

У меня есть два взаимозаменяемых класса, реализованных в виде слоев для чтения этих данных. Один из них использует RandomAccessFile, который прекрасно работает и все.

Плохо:

Другой (тот, о котором этот вопрос в основном) пытается использовать FileInputStream и DataInputStream, чтобы те же самые данные можно было (хотя бы теоретически) прочитать в конфигурации Java MIDP 2.0 (CLDC 1.1) (которая не имеет RandomAccessFile).

В этом классе я открываю файл данных так:

FileInputStream res = new FileInputStream(new File(filename));
h = new DataInputStream(res);

... и реализовать seek() / skip() следующим образом (position - это long, который записывает текущую позицию в файле):

public void seek(long pos) throws java.io.IOException {

    if (! this.isOpen()) {
        throw new java.io.IOException("No file is open");
    }

    if (pos < position) {
        // Seek to the start, then skip some bytes
        this.reset();
        this.skip(pos);
    } else if (pos > position) {
        // skip the remaining bytes until the position
        this.skip(pos - position);
    }
}

и

public void skip(long bytes) throws java.io.IOException {

    if (! this.isOpen()) {
        throw new java.io.IOException("No file is open");
    }

    long skipped = 0, step = 0;

    do {
        step = h.skipBytes((int)(bytes - skipped));
        if (step < 0) {
            throw new java.io.IOException("skip() failed");
        }
        skipped += step;
    } while (skipped < bytes);

    position += bytes;
}

Безобразный:

Проблема со вторым классом (FileInputStream / DataInputStream one) заключается в том, что иногда он решает сбросить позицию файла в какое-то странное место в файле :) Это происходит как при запуске этого на J2SE (a компьютер) и J2ME (мобильный телефон). Вот пример фактического использования этого класса читателя и возникшей ошибки:

// Open the data file
Reader r = new Reader(filename);

// r.position = 0, actual position in a file = 0

// Skip to where the data block that is needed starts
// (determined by some other code)
r.seek(189248);

// r.position = 189248, actual position in a file = 189248

// Do some reading...
r.readID(); r.readName(); r.readSurname();

// r.position = 189332, actual position in a file = 189332

// Skip some bytes (an unneeded record)
r.skip(288);

// r.position = 189620, actual position in a file = 189620

// Do some more reading...
r.readID(); r.readName(); r.readSurname();

// r.position = 189673, actual position in a file = 189673

// Skip some bytes (an unneeded record)
r.skip(37);

// AAAAND HERE WE GO:
// r.position = 189710, actual position in a file = 477

Мне удалось определить, что, когда меня попросили пропустить еще 37 байтов, Java позиционировала указатель файла на байт 477 с самого начала или вместо файла.

«Свежий» (сразу после открытия файла) поиск позиции 189710 (и далее) работает нормально. Однако повторное открытие файла каждый раз, когда мне нужен seek(), очень болезненно медленное, особенно на мобильном телефоне.

Что случилось?

1 Ответ

0 голосов
/ 19 октября 2010

Я не вижу ничего плохого в этом. Вы положительно оценили значение r.position перед последним пропуском? Если в потоках JDK нет основной ошибки или если у вас есть несколько потоков, использующих Reader, то я могу только догадываться, что что-то неправильно изменяет значение позиции при чтении ваших полей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...