writeInt (Integer) перезаписывает ноль - PullRequest
0 голосов
/ 25 февраля 2019

Используя RandomAccessFile класс, я пытаюсь проверить концепцию записи / чтения в / из файла в Java.Поэтому я попробовал этот код:

public static void main (String[] args) throws IOException {
        RandomAccessFile storage = new RandomAccessFile("FILE.txt", "rw");

        storage.seek(0);
        storage.writeInt(1);

        storage.seek(1);
        storage.writeInt(2);

        storage.seek(2);
        storage.writeInt(3);

        storage.seek(3);
        storage.writeInt(4);

        storage.seek(4);
        storage.writeInt(5);

        System.out.println(storage.readInt());
        System.out.println(storage.readInt());
        System.out.println(storage.readInt());
        System.out.println(storage.readInt());
        System.out.println(storage.readInt());

        storage.close();

Я думаю, что он должен напечатать: 1 2 3 4 5

но что происходит, когда он печатает: 3 4 5 EOFException ... почему?

Ответы [ 2 ]

0 голосов
/ 25 февраля 2019

Здесь есть 2 проблемы - вы не разрешаете 4 байта на int записанные, и вы не пытаетесь вернуться к началу файла при чтении int s обратно в память.

Во-первых, метод seek принимает аргумент количества байтов в качестве смещения в файле.

pos - позиция смещения, измеренная в байтах от начала файла, вдля установки указателя файла.

Но в Java int s имеет 4 байта, поэтому вы перезаписываете 3 из 4 предыдущих байтов int при каждой последующей записи.Либо явно устанавливайте метку на 4 байта позже каждый раз:

storage.seek(4);
storage.writeInt(2);

storage.seek(8);
storage.writeInt(3);

// etc.

Или, что еще проще, метка «делает правильные вещи» и продвигается на соответствующее количество байтов.Просто пропустите seek s здесь.

storage.writeInt(1);
storage.writeInt(2);
storage.writeInt(3);
storage.writeInt(4);
storage.writeInt(5);

Вторая проблема заключается в том, что при чтении байтов назад вы не сбрасываете метку обратно в начало файла, вызывая EOFException,Добавьте вызов к seek(0), чтобы отправить метку обратно в начало файла.

storage.seek(0);

System.out.println(storage.readInt());
System.out.println(storage.readInt());
System.out.println(storage.readInt());
System.out.println(storage.readInt());
System.out.println(storage.readInt());

Затем я получаю вывод:

1
2
3
4
5
0 голосов
/ 25 февраля 2019

Я вижу здесь две проблемы:

  1. Вы не seek находитесь между последней записью и первым чтением, поэтому вы начинаете чтение после окончания того места, где вы в последний разнаписал.(Тот факт, что вы не немедленно получаете EOFException, означает, что ваш файл не был пустым в начале выполнения этой программы.)
  2. seek принимает аргумент, представляющий байтпозиции, но writeInt и readInt пишите и читайте четыре байта.Поэтому, если вы не хотите, чтобы ваши целые числа перекрывали друг друга, вам нужно искать позиции 0, 4, 8 и т. Д., А не 0, 1, 2 и т. Д. (Хотя, как это бывает, вы нена самом деле вам нужны ваши текущие вызовы seek, если ваша цель - чтобы целые числа были смежными.)
...