2015-01-29 1 views
0

Я пишу программу на Java, которую планирую использовать для моддинга определенной видеоигры путем изменения двоичных данных игры. Он хранится в файле .dat, который просто содержит байты данных игры. То, с чем я работал, - FileInputStream для чтения в файле и FileOutputStream для изменения содержимого. Однако, насколько мне известно, FileOutputStream способен модифицировать только конец файла, а не содержимое в середине.Изменение содержимого двоичного файла в Java

То, что я хочу, чтобы иметь возможность сделать следующее:

Если это двоичный файл при условии:

06 B4 45 18 A7 DD 

Я хотел бы быть в состоянии, например, изменить байт в положении n = 3 и измените его на значение v = FF.

в результате:

06 B4 45 FF A7 DD 

Я хотел бы написать эти данные обратно в файл затем.

Что было бы лучшим способом решить эту проблему? Прямо сейчас, единственный способ, которым я мог видеть FileOutputStream, - это, если я действительно взял исходный файл и восстановил его от начала до конца, но заменив новые значения в этом процессе. Однако это кажется действительно неэффективным, учитывая, что файлы, которые я планирую изменить, содержат примерно 20 000 байт каждый.

Я чувствую, что должен быть более простой способ. Какие-либо предложения?

+0

Это не такая штука, как шестнадцатеричный файл. Это двоичный файл. Он - просто представление для показа. – EJP

+0

'FileOutputStream' * может * 'присоединить' к существующему файлу в конце или полностью заменить его с самого начала. Да, вам нужно будет прочитать и переписать все это, поэтому лучше ответить на @ Eggen «RandomAccessFile». Но 20 000 байт могут быть предметом озабоченности 40 лет назад; на сегодняшних машинах это незаметно. JVM, который запускает вашу программу Java, обычно составляет от 20 000 000 до 50 000 000 байтов и часто в 10 раз больше или больше. –

ответ

1

Вам нужен RandomAccessFile. Этого было бы достаточно, но для повышения производительности вы можете использовать getChannel() и ByteBuffer.

Как известно, RandomAccessFile позволяет позиционировать в любом месте и читать и писать.

try (RandomAccessFile fh = new RandomAccessFile(file, "rw")) { 
    fh.seek(3L); 
    int old = fh.read(); // 0x18 
    fh.seek(3L); 
    fh.write(0xBB); 
} 
+0

Фантастический, это делает именно то, что я хочу. Благодаря! –