Запись данных в файл с помощью RandomAccessFile

Я пишу в файл, используя RandomAccessFile. Данные (поля) хранятся с фиксированной длиной поля, например, каждому полю будет выделено пространство в 16 байт. Я что-то пишу, помещая указатель в соответствующую позицию, используя seek(). Проблема возникает, когда я перезаписываю некоторые поля, т. Е. Если «Бангалор» был сохранен ранее, а если перезаписать его «Дели», результатом будет «Делилор». Как полностью стереть «Бангалор» перед написанием «Дели»?

Если значение — это строка, которую я хочу написать, а длина — это фиксированная длина поля (16)

        byte[] b=new byte[length];

        b=value.getBytes();

        try 
        {
            database.seek(offset);
            database.write(b);


        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();

        }

person Sameer Sarmah    schedule 14.03.2014    source источник
comment
вам нужно записать полные 16-байтовые фрагменты, чтобы перезаписать старое значение.   -  person kofemann    schedule 14.03.2014
comment
Учитывая то, что вы делаете, было бы лучше, если бы вы использовали сопоставление файлов; это разрешит все те системные вызовы, которые вы используете в настоящее время. По сути, как минимум у вас есть seek() и write() каждый раз, когда вы записываете запись. Использование сопоставления позволит избежать этих двух   -  person fge    schedule 14.03.2014
comment
@tigran : байт [] b = новый байт [длина]; и база данных.write(b); должны сделать это правильно? или мне нужно добавить больше кода, чтобы записать все 16 байтов.   -  person Sameer Sarmah    schedule 14.03.2014
comment
Ваш текущий код не работает. Сразу же после этого вы переназначаете b на value.getBytes().   -  person fge    schedule 14.03.2014


Ответы (1)


Вам нужно перезаписать полные 16 байт. Пример того, как это сделать:

ByteBuffer buf = ByteBuffer.allocate(16);
buf.put(value.getBytes("UTF-8"));
database.seek(offset);
database.write(buf.array());

Это будет записывать конечные нули после содержимого записи.

Обратите внимание, однако, что для каждой записи, которую вы записываете, это включает два системных вызова, которых вы можете избежать, если используете сопоставление памяти файла. См. FileChannel.map().

person fge    schedule 14.03.2014
comment
: Как записать строку 1 в виде массива байтов. Всякий раз, когда я использую ByteBuffer buf =ByteBuffer.allocate(RECORD_FLAG_BYTES); buf.put(deleteFlag.getBytes(UTF-8)); база данных.запись (buf.array()); пишет 49. - person Sameer Sarmah; 14.03.2014