Lesen Sie Binärdateien in Java 1

Einführung

Dies ist die Methode, die ich vor einiger Zeit entwickelt habe. Keine bewährte Methode. Ich mag Objektorientierung (˘ω˘)

Basic

Machen Sie die Datei zu einem ByteBuffer

Extrahieren Sie zuerst aus InputStream in Byte []. Informationen zum Herausnehmen finden Sie unter hier. Wickeln Sie es ein, um einen ByteBuffer (im Folgenden buf) zu erstellen.

byte[] bin = BinUtil.readAll(stream);
ByteBuffer buf = ByteBuffer.wrap(bin);

Zum Lesen von 4 Bytes von buf als signiert

(long)buf.getInt()

4 Bytes von buf als vorzeichenlos lesen

In Java gibt es kein Vorzeichenkonzept (˘ω˘).

(long)buf.getInt () & 0xffffffffL

Definieren

Datentypschnittstelle

Sie müssen in der Lage sein, Daten von buf zu erhalten und zu erhalten. Bereiten Sie das Kompilieren und Dekompilieren vor. Die Gesamtlänge und der Versatz der Datengröße (später beschrieben) sind ebenfalls erforderlich.


public interface DataTypeInterface<T> {
    Integer getOffset();

    void setOffset(Integer offset);

    Integer getSize();

    void setSize(Integer size);

    void decompile(ByteBuffer buf);

    void compile(ByteBuffer buf);

    /**
     *Holen Sie sich untergeordnete Elemente
     *
     * @untergeordnetes Element zurückgeben
     */
    T get();

    /**
     *Legen Sie untergeordnete Elemente fest
     *
     * @param item Untergeordnetes Element
     */
    void set(T item);
}

Für einfache Datenstrukturen

Ein Typ, dessen interner Wert durch ein Java-Grundelement (z. B. String oder Long) dargestellt werden kann.

public abstract class SingleDataType<T> implements DataTypeInterface<T>{

    /**
     *Interner Wert
     */
    private T value;

    /**
     *Objektstartposition im Bytestrom
     */
    private Integer offset;

    /**
     *Objektbyte-Größe
     */
    private Integer size;

    @Override
    final public Integer getOffset(){
        return this.offset;
    }

    @Override
    final public void setOffset(Integer offset){
        this.offset=  offset;
    }

    @Override
    final public void setSize(Integer size) {
        this.size = size;
    }

    @Override
    public Integer getSize() {
        return this.size;
    }

    public T get() {
        return this.value;
    }

    public void set(T value) {
        this.value = value;
    }
}

Erstellen Sie eine abstrakte Klasse für Zahlen

Nur Zahlen.

abstract public class NumericDataType<T extends Number> extends SingleDataType<T> {

    @Override
    final public T get() {
        return super.get();
    }

    @Override
    public void set(T val) {
         super.set(val);
    }

    abstract public void setNumber(Number val);

}

LONG Grundsätzlich lange gemacht (゜ ∀ ゜)

public class LONG extends NumericDataType<Long> {

    @Override
    public void decompile(ByteBuffer buf) {
        this.setOffset(buf.position());
        this.set((long)buf.getInt());
    }

    @Override
    public void compile(ByteBuffer buf) {
        this.setOffset(buf.position());
        buf.putInt(this.get().intValue());
    }

    public LONG(ByteBuffer buf) {
        this.decompile(buf);
        this.setSize(4);
    }

    public LONG(Long value) {
        this.set(value);
        this.setSize(4);
    }

    /**
     *Überprüfen Sie den Wert und legen Sie ihn fest
     *
     * @Parameterwert Wert
     * @Der Bereich der IllegalArgumentException-Werte für Würfe ist-Wenn es weniger als 2147483648L oder mehr als 2147483647L ist
     */
    @Override
    public void set(Long value) throws IllegalArgumentException {
        /*1*/
        if (  value < -2147483648L ||  2147483647L < value) {
            throw new IllegalArgumentException("Der Wertebereich überschreitet die maximale und minimale Länge");
        }
        /*2*/
        super.set(value);
    }

    @Override
    public void setNumber(Number val) {
        this.set(val.longValue());
    }
}

Für komplexe Datenstrukturen

In Java gibt es kein Konzept von struct (; ω;). Ich werde etwas mit Anmerkungen und Überlegungen machen

@Retention(RetentionPolicy.RUNTIME)
public @interface PROPERTY {
    int order();
}

Zählen Sie die Felder durch Reflexion auf, extrahieren Sie nur die Felder mit den obigen Anmerkungen, sortieren Sie sie in der richtigen Reihenfolge und dekompilieren Sie sie in dieser Reihenfolge.


public abstract class CompositeDataType implements DataTypeInterface<DataTypeInterface>{

    protected Integer offset;

    @Override
    final public Integer getOffset(){
        return this.offset;
    }

    @Override
    final public void setOffset(Integer offset){
        this.offset=  offset;
    }

    @Override
    public Integer getSize(){
        return this.OrderedProperties()
                .entrySet()
                .stream()
                .mapToInt(item -> item.getValue().getSize())
                .sum();
    }

    @Override
    @Deprecated
    public void setSize(Integer size) {
        throw new RuntimeException("Sie können die Größe eines zusammengesetzten Objekts nicht festlegen.");
    }

    @Override
    public void decompile(ByteBuffer buf){
        this.setOffset(buf.position());
        for (Map.Entry<String, DataTypeInterface> item: this.OrderedProperties().entrySet()) {
            try {
                item.getValue().decompile(buf);
            }catch (IllegalArgumentException e){
                System.out.println("Schlüssel("+ item.getKey() +")Untergeordnete Elemente von werden übersprungen");
                e.printStackTrace();
            }
        }
    }

    @Override
    public void compile(ByteBuffer buf) {
        this.setOffset(buf.position());
        for (Map.Entry<String, DataTypeInterface> item: this.OrderedProperties().entrySet()) {
            try {
                item.getValue().compile(buf);
            }catch (IllegalArgumentException e){
                System.out.println("Schlüssel("+ item.getKey() +")Untergeordnete Elemente von werden übersprungen");
                e.printStackTrace();
            }
        }
    }

    protected Map<String,DataTypeInterface> OrderedProperties() {

        List<Field> fields=new ArrayList<>();
        Class c= this.getClass() ;
        while(c != null){
            fields.addAll(java.util.Arrays.asList(c.getDeclaredFields()));
            c = c.getSuperclass();
        }

        List<Field> paramfields = fields
                .stream()
                .filter(f -> f.getAnnotation(PROPERTY.class) != null)
                .collect(Collectors.toList());

        Collections.sort(paramfields, (Field o1, Field o2) -> {
                    PROPERTY or1 = o1.getAnnotation(PROPERTY.class);
                    PROPERTY or2 = o2.getAnnotation(PROPERTY.class);

                    if (or1 != null && or2 != null) {
                        return or1.order() - or2.order();
                    }
                    return o1.getName().compareTo(o2.getName());
                }
        );

        Map<String, DataTypeInterface> m = new LinkedHashMap<>();

        try {
            for (Field f : paramfields) {
                f.setAccessible(true);
                m.put(f.getName(), (DataTypeInterface) f.get(this));
            }
        } catch (IllegalAccessException e) {
            throw new RuntimeException("Feld("+ fields.toString() +"Habe keinen Zugriff");
        }

        return m;

    }

    @Override
    public DataTypeInterface get() {
        return null;
    }

    @Override
    public void set(DataTypeInterface item) {
    }
}

Wenn Sie eine Datenstruktur haben, verwenden Sie diese wie folgt.


public class Version extends CompositeDataType {

    @PROPERTY(order = 1)
    public LONG version = new LONG();

    @PROPERTY(order = 2)
    public LONG subVersion = new LONG();
}

Sie können wiederverwenden, was Sie machen.

public class Data1 extends CompositeDataType {

    @PROPERTY(order = 1)
    public Version version = new Version();

    @PROPERTY(order = 2)
    public LONG data1 = new LONG();
}

Dies sind die Grundlagen, und 2 gilt für Array- und Offsetdaten.

Recommended Posts

Lesen Sie Binärdateien in Java 1
Lesen Sie Binärdateien in Java 2
Einfaches Lesen von Textdateien in Java (Java 11 & Java 7)
Lesen Sie JSON in Java
Lesen Sie die Standardeingabe in Java
Lesen Sie die Java-Eigenschaftendatei in C #
Lesen Sie CSV in Java (Super CSV Annotation)
Erstellen Sie Binärdaten variabler Länge in Java
TCP-Kommunikation (Socket-Kommunikation) in Java (ASCII, Binär)
Partisierung in Java
Änderungen in Java 11
Java-How zum Vergleichen von Bilddateien in Binärform
Janken in Java
Konvertieren Sie SVG-Dateien in Java in PNG-Dateien
Lesen Sie Felica mit RC-S380 (PaSoRi) in Java
Spielen Sie RAW-, WAV- und MP3-Dateien in Java ab
Lesen Sie die xlsx-Datei in Java mit Selenium
Umfangsrate in Java
FizzBuzz in Java
Lesen und Schreiben von GZIP-Dateien in Java
Lesen Sie eine Zeichenfolge in einer PDF-Datei mit Java
Hinzufügen, Lesen und Löschen von Excel-Kommentaren mit Java
[Java] Dateien in src / main / resources lesen
Importieren Sie Dateien derselben Hierarchie in Java
Machen Sie einen Blackjack mit Java
Einschränkungsprogrammierung in Java
Setzen Sie Java8 in Centos7
NVL-artiger Typ in Java
Verbinden Sie Arrays in Java
"Hallo Welt" in Java
Java-Eigenschaftendatei lesen
Aufrufbare Schnittstelle in Java
Kommentare in der Java-Quelle
Azure funktioniert in Java
Formatieren Sie XML in Java
Einfache HTML-Spezialchars in Java
Boyer-Moore-Implementierung in Java
Lesen Sie die Java HashMap-Quelle
Hallo Welt in Java
Verwenden Sie OpenCV mit Java
WebApi-Memorandum mit Java
Typbestimmung in Java
Befehle in Java ausführen (Ping)
Verschiedene Threads in Java
Implementierung der Heap-Sortierung (in Java)
Zabbix API in Java
ASCII-Kunst in Java
Listen in Java vergleichen
POST JSON in Java
Fehler in Java ausdrücken
Erstellen Sie JSON in Java
Datumsmanipulation in Java 8
Was ist neu in Java 8?
Verwenden Sie PreparedStatement in Java
Was ist neu in Java 9,10,11
Parallele Ausführung in Java
Lesen Sie die Paketerfassung, die von tcpdump mit Java erhalten wurde
Wie kann ich IBM Mainframe-Dateien in Java eingeben / ausgeben?
Android-Laden Sie Bilddateien in den Azure Blob-Speicher in Java hoch