Lire des fichiers binaires en Java 1

introduction

C'est la méthode que j'ai proposée il y a quelque temps. Pas une meilleure pratique. J'aime l'orientation des objets (˘ω˘)

De base

Faire du fichier un ByteBuffer

Tout d'abord, extrayez de InputStream vers l'octet []. Veuillez consulter ici pour savoir comment le retirer. Enveloppez-le pour créer un ByteBuffer (ci-après buf).

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

Pour lire 4 octets de buf comme signé

(long)buf.getInt()

Pour lire 4 octets de buf comme non signés

Il n'y a pas de concept de signe en Java (˘ω˘).

(long)buf.getInt () & 0xffffffffL

Définir

--Définissez l'interface du type de données.

Interface de type de données

Vous devez pouvoir obtenir et obtenir des données de buf. Préparez la compilation et la décompilation. La longueur et le décalage de la taille totale des données (décrits plus loin) sont également requis.


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

    void setOffset(Integer offset);

    Integer getSize();

    void setSize(Integer size);

    void decompile(ByteBuffer buf);

    void compile(ByteBuffer buf);

    /**
     *Obtenir des éléments enfants
     *
     * @retourner l'élément enfant
     */
    T get();

    /**
     *Définir les éléments enfants
     *
     * @élément param Elément enfant
     */
    void set(T item);
}

Pour des structures de données simples

Un type dont la valeur interne peut être représentée par une primitive java (telle que String ou Long).

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

    /**
     *Valeur interne
     */
    private T value;

    /**
     *Position de début de l'objet dans le flux d'octets
     */
    private Integer offset;

    /**
     *Taille d'octet de l'objet
     */
    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;
    }
}

Créer une classe abstraite pour les nombres

Seulement les chiffres.

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 Fondamentalement fait long (゜ ∀ ゜)

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);
    }

    /**
     *Validez et définissez la valeur
     *
     * @valeur de paramètre valeur
     * @La plage des valeurs de jette IllegalArgumentException est-S'il est inférieur à 2147483648L ou supérieur à 2147483647L
     */
    @Override
    public void set(Long value) throws IllegalArgumentException {
        /*1*/
        if (  value < -2147483648L ||  2147483647L < value) {
            throw new IllegalArgumentException("La plage de valeurs dépasse les longueurs maximale et minimale");
        }
        /*2*/
        super.set(value);
    }

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

Pour les structures de données complexes

Il n'y a pas de concept de struct en Java (; ω;). Je ferai quelque chose avec des annotations et une réflexion

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

Énumérer les champs par réflexion, extraire uniquement ceux avec les annotations ci-dessus, les trier dans l'ordre et décompiler dans cet ordre.


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("Vous ne pouvez pas définir la taille d'un objet composite.");
    }

    @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("Clé("+ item.getKey() +")Les éléments enfants de sont ignorés");
                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("Clé("+ item.getKey() +")Les éléments enfants de sont ignorés");
                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("champ("+ fields.toString() +"Ne peut pas accéder");
        }

        return m;

    }

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

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

Si vous avez une structure de données, utilisez-la comme suit.


public class Version extends CompositeDataType {

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

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

Vous pouvez réutiliser ce que vous faites.

public class Data1 extends CompositeDataType {

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

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

Ce sont les bases, et 2 est pour les données de tableau et les données de décalage.

Recommended Posts

Lire des fichiers binaires en Java 1
Lire des fichiers binaires dans Java 2
Lisez facilement les fichiers texte en Java (Java 11 et Java 7)
Lire JSON en Java
Lire l'entrée standard en Java
Lire le fichier de propriétés Java en C #
Lire CSV en Java (annotation Super CSV)
Créer des données binaires de longueur variable en Java
Communication TCP (communication socket) en Java (ASCII, Binaire)
Partition en Java
Changements dans Java 11
Java-Comment comparer des fichiers image en binaire
Janken à Java
Convertir des fichiers SVG en fichiers PNG en Java
Lire Felica en utilisant RC-S380 (PaSoRi) en Java
Lecture de fichiers RAW, WAV, MP3 en Java
Lire le fichier xlsx en Java avec Selenium
Taux circonférentiel à Java
FizzBuzz en Java
Lire et écrire des fichiers gzip en Java
Lire une chaîne dans un fichier PDF avec Java
Ajouter, lire et supprimer des commentaires Excel à l'aide de Java
[Java] Lire les fichiers dans src / main / resources
Importer des fichiers de la même hiérarchie en Java
Faites un blackjack avec Java
Programmation par contraintes en Java
Mettez java8 dans centos7
NVL-ish guy en Java
Joindre des tableaux en Java
"Hello World" en Java
Lire le fichier de propriétés Java
Interface appelable en Java
Commentaires dans la source Java
Fonctions Azure en Java
Formater XML en Java
Simple htmlspecialchars en Java
Implémentation Boyer-Moore en Java
Lire la source Java HashMap
Hello World en Java
Utiliser OpenCV avec Java
Mémorandum WebApi avec Java
Détermination de type en Java
Exécuter des commandes en Java (ping)
Divers threads en java
Implémentation du tri de tas (en java)
API Zabbix en Java
Art ASCII à Java
Comparer des listes en Java
POST JSON en Java
Exprimer l'échec en Java
Créer JSON en Java
Manipulation de la date dans Java 8
Nouveautés de Java 8
Utiliser PreparedStatement en Java
Nouveautés de Java 9,10,11
Exécution parallèle en Java
Lire la capture de paquets obtenue par tcpdump avec Java
Comment entrer / sortir des fichiers mainframe IBM en Java?
Android-Télécharger des fichiers image vers Azure Blob Storage en Java