Member 13602192 Ответов: 1

Как прочитать любой большой файл в шестнадцатеричном формате с помощью java (file hex viewer)


Здравствуйте эксперты, пожалуйста, мне нужна помощь с этим кодом, я создал его для просмотра шестнадцатеричных файлов, но он не читает большие файлы, потому что хранит данные в памяти, что в свою очередь выдает ошибку"OutOfMemory". Я хочу иметь возможность просматривать заклятие вот так http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.github.javadev%22%20AND%20a%3A%22hexeditor%22 Он может просматривать файлы размером до 9 экзабайт, как он утверждает;

1. Как я могу изменить свой код, чтобы сделать то же самое?
2. Что мне нужно добавить, удалить или изменить, пожалуйста?

На самом деле я новичок, так что если вы поможете мне с кодом, пожалуйста, некоторые объяснения будут хороши, я не хочу быть грубым или если я прошу слишком много, пожалуйста, простите. Спасибо

<pre>import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import javax.swing.JFileChooser;

/**
 *
 * @author kingamada
 */
public class HexViewer {

    /**
     * @param args the command line arguments
     * @throws java.io.FileNotFoundException
     */
    public static void main(String[] args) throws FileNotFoundException, IOException {
        InputStream is = null;
        JFileChooser open = new JFileChooser();
            open.showOpenDialog(null);
            File f = open.getSelectedFile();
            is = new BufferedInputStream(new FileInputStream(f));
            int bytesCounter = 0;
            int value;
            StringBuilder set = new StringBuilder();
            StringBuilder sbResult = new StringBuilder();
            while ((value = is.read()) != -1) {
                //convert to hex value with "X" formatter
                set.append(String.format("%02X ", value));
                //if 90 bytes are read, reset the counter,
                if (bytesCounter == 90) {
                    sbResult.append(set).append("\n");
                    bytesCounter = 0;
                    
                } else {
                    bytesCounter++;   
                }
                System.out.print(set);
                set.setLength(0);
                
            }       
            if (bytesCounter != 0) {
                //add spaces more formatting purpose only
                for (; bytesCounter < 90; bytesCounter++) {
                    //1 character 3 spaces
                    set.append("   ");
                }
                sbResult.append(set).append("\n");
                
            }
            
    }
    
}


Что я уже пробовал:

Я использовал byte[] для чтения файла по частям, но он не записывает шестнадцатеричный код
<pre lang="java"><pre>import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import javax.swing.JFileChooser;

/**
 *
 * @author kingamada
 */
public class HexViewer {

    /**
     * @param args the command line arguments
     * @throws java.io.FileNotFoundException
     */
    public static void main(String[] args) throws FileNotFoundException, IOException {
        InputStream is = null;
        JFileChooser open = new JFileChooser();
            open.showOpenDialog(null);
            File f = open.getSelectedFile();
            is = new BufferedInputStream(new FileInputStream(f));
            int bytesCounter = 0;
            byte[] buffer= new byte[1024];
            int value;
            StringBuilder set = new StringBuilder();
            StringBuilder sbResult = new StringBuilder();
            while ((value = is.read(buffer)) != -1) {
                //convert to hex value with "X" formatter
                set.append(String.format("%02X ", value));
                //if 90 bytes are read, reset the counter,
                if (bytesCounter == 90) {
                    sbResult.append(set).append("\n");
                    bytesCounter = 0;
                    
                } else {
                    bytesCounter++;   
                }
                System.out.print(set);
                set.setLength(0);
                
            }       
            if (bytesCounter != 0) {
                //add spaces more formatting purpose only
                for (; bytesCounter < 90; bytesCounter++) {
                    //1 character 3 spaces
                    set.append("   ");
                }
                sbResult.append(set).append("\n");
                
            }
            
    }
    
}


Я также проверяю этот шестнадцатеричный редактор http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.github.javadev%22%20AND%20a%3A%22hexeditor%22 , но при чтении исходного кода я не могу узнать, где и как автор этого добился.

1 Ответов

Рейтинг:
0

Dave Kreskowiak

Во-первых, вы просто читаете байты, а не "Hex". Шестнадцатиричное представление значение в системе счисления с основанием 16 используют люди.

Вам просто нужно прочитать "страницы" данных из файла. Что такое "страница"? Легко, Сколько байтов вы можете показать на своем дисплее данных файла? Там есть страница. Вы читаете это количество байтов из файла, начиная со смещения. Если вы показываете, скажем, 512 байт на экране, то первая страница находится со смещением 0, Следующая страница-со смещением 512, 1024, ... Просто прочитайте страницу, которую вам нужно показать.

Как вы можете поддерживать такие массивные файлы? Не используйте 32-битные целые числа для отслеживания смещения. Вместо этого используйте 64-битное целое число без знака, которое обычно называется "unsigned long". Например, чтение 250 000 000 страниц будет смещено на 128 000 000 000 байт в файл. Это не будет вписываться в 32-битное целое число без знака, но оно будет вписываться в 64-битное целое число.

Я не могу сказать вам, как изменить ваш код. Я не занимаюсь Java. Но я только что дал вам рамки.