Fichiers à accès direct

boustry
Fichiers à accès direct

Bonjour à tous les grands buveurs de café :)

Ancien programmeur C je suis familier des fonctions d'entrées/sorties read, fread, write, fwrite.

Mais nouveau venu dans la programmation Java, j'avoue que je me perds un peu dans toutes ces classes de flots :oops:
Existe-t-il un moyen avec Java de lire des fichiers binaires existans en écrivant un code aussi concis et direct qu'on le ferait en C ?

K-lo

Essaies avec les classes FileInputStream et FileOutputStream
Regarde ici ça peut t'aider.

Désolé du peu d'aide que je fournis, moi je suis resté à C++ :wink:

fredericmazue

Pour un accès direct au plus bas niveau, je crois que c'est la classe RandomAccessFile qu'il faut utiliser. L'intérêt majeur est qu'il y a une méthode seek, comme en C et travailler avec cette classe et, je pense, ce qui se rapproche le plus de la programmation C

Le problème potentiel est que Java utilise le BigEndian, tandis que C sur une architecture x86 aura à coup sûr écrit les données binaires en LittleEndian. Donc si tu lis en entier codé sur 4 octects depuis un fichier binaire C, tu dois permuter les octets pour que la valeur soit correcte en Java.

Les classes FileInputStream et FileOutpstrem suggérés par k-lo ont aussi leur intérêt. Par contre elles n'ont pas, je crois, l'équivalent d'une méthode seek pour faire un accès direct. Ce sont comme leur nom l'indique des classes de flux., donc de plus haut niveau

thesuixx

tu peux utiliser le DataInputStream:

// l'encodage: sur 2 octets
public static final int NB_BYTES_ENCODAGE = 2;
// le flux       
in = new DataInputStream(new FileInputStream(fichierBinaire));
// le tableau servant à temporairement stocker les bytes
byte[] byteArray = new byte[NB_BYTES_ENCODAGE];

// lecture du fichier
while (in.read(byteArray) != -1)
         System.out.println(byteArrayToInt(byteArray));

et voici la fonction pour obtenir tes valeurs:

    /**
     * extrait la valeur int d'un byte array en big endian
     * @param byteArray: un byte array en ordre big endian
     * @return int
     */
    private int byteArrayToInt(byte[] byteArray) {
        int total = 0;
        for (int i = 0; i < byteArray.length; i++) {
            total += unsignedByteToInt(byteArray[i]) * (i == 0 ? 1 : i*256);
        }
        return total;
    }
    
    /**
     * effectue la conversion d'un byte en int en traitant le byte comme s'il était unsigned
     * @param b: le byte
     * @return la valeur int du byte comme s'il était unsigned
     */
    private int unsignedByteToInt(byte b){
        int res = (int)b;
        if (res < 0){
            res = 256 + res;  // voir complément à deux
        }
        return res;
    }

* si les valeurs sont signées, tu ne fais pas appel à unsignedbyteToInt mais tu prends la vraie valeur de l'octet

EDIT: me suis trompé, ca ne marche qu'avec un encodage sur 2 octets, si tu as un encodage sur 4 ou 8 tu permutes les octets 2 par 2 dans byteArrayToInt