IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

lecture ecriture de fichier par blocs


Sujet :

C

  1. #1
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    947
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 947
    Points : 1 351
    Points
    1 351
    Par défaut lecture ecriture de fichier par blocs
    Salut,

    Pour les besoins d'un vieux 8 bits, J'aurai besoin d'émuler un disque sur PC. Pour les petits disques, pas de problème, on les charge en mémoire à partir d'un fichier sous forme de tableaux de secteurs qui sont eux même des tableaux de char. Inconvénient: Il faut mettre entièrement les disques en mémoire, Ca ne va que pour les petits disques, mais ça a le mérite de marcher. Les fonctions demandées sont:
    -formatage d'un secteur
    -écriture d'un secteur dans un buffer
    -écriture d'un buffer dans un secteur.

    Pour des disques de plusieurs mégas, j'aimerais charger un secteur de/vers la mémoire vers/depuis un fichier. Comme ça, après chaque lecture écriture de secteur, je ferme le fichier image entre chaque accès. Le problème, c'est qu'en mode "rwb", quand je positionne le curseur à l'offset du secteur xxx, tout ce qui est avant ledit secteur est mis à zéro et le fichier est tronqué dès la fin du secteur.

    Je me demande donc comment créer un fichier de taille définie et définitive, et y lire et y écrire par bloc avec les fonctions fseek fread et fwrite. J'échoue sur l'écriture de secteur, qui me détruit le fichier à part ledit secteur. Je me demande même si c'est possible...

    A+

    Pfeuh

  2. #2
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par pfeuh Voir le message
    Je me demande donc comment créer un fichier de taille définie et définitive, et y lire et y écrire par bloc avec les fonctions fseek fread et fwrite. J'échoue sur l'écriture de secteur, qui me détruit le fichier à part ledit secteur. Je me demande même si c'est possible...
    Les fonctions standard du C ne savent pas ce qu'est un secteur. elles voient le disque comme un flux d'octets.

    Si tu veux accéder au disque par secteurs, il faut utiliser des fonctions systèmes de très bas niveau comme BIOS INT 13H ou, sous Windows :

    http://support.microsoft.com/kb/100027

  3. #3
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    947
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 947
    Points : 1 351
    Points
    1 351
    Par défaut
    Salut,

    Merci Emmanuel, ça, je l'ai bien compris, je pense que tu as lu en diagonale. J'essaie juste d'émuler un disque dur (pour un émulateur, justement) qui serait en fait un (gros) fichier. Donc le seul moyen d'accèder à un secteur "émulé", c'est de lire et écrire le fichier par bloc de la taille d'un secteur.

    A+

    Pfeuh

  4. #4
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Citation Envoyé par pfeuh Voir le message
    Le problème, c'est qu'en mode "rwb", quand je positionne le curseur à l'offset du secteur xxx, tout ce qui est avant ledit secteur est mis à zéro et le fichier est tronqué dès la fin du secteur.
    Tu dois avoir un problème ailleurs car cela me semble bon comme approche. On peut voir ton code ?

    Autre remarque, cette méthode risque de te limiter à des disques émulés de 2GO car les déplacements dans un fichier se font sur nombre signé de 32 bits (bon dans ton cas, ce n'est peut être pas un problème mais ne le perd pas de vue).

  5. #5
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Dans mon souvenir, l'ouverture en 'w' réinitialise le fichier. Utilise plutôt 'a' (en reprenant ce que tu fourni:"a+b").

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Je ne crois pas que "rw" soit un mode de fichier légal. Utilise plutôt "r+" ou "w+" (sans oublier le "b", bien sûr).

  7. #7
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    947
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 947
    Points : 1 351
    Points
    1 351
    Par défaut
    Salut,

    Voilà les bouts de code, désolé pour leur longueur... Et merci pour les pistes je vais regarder ça tranquillement ce soir.

    A+

    Pfeuh

    datatypes.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    #ifndef DATATYPES
        #define DATATYPES
     
        typedef unsigned char      Bool;
        typedef unsigned char      UByte;
        typedef unsigned char      Byte;
        typedef short unsigned int UWord;
        typedef short int          Word;
        typedef unsigned int       ULong;
        typedef long               Long;
        typedef float              Float;
        typedef short unsigned int UInt;
        typedef short int          Int;
     
        #ifndef __RELEASE__
            #define __DEBUG__
        #else
            #ifdef __DEBUG__
                #undef __DEBUG__
            #endif
        #endif
     
    #endif
    test_harddisk.c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <assert.h>
    #include "hw_harddisk.h"
     
    #define HARDDISK_NAME "harddisk.bin"
    #define SECTORS 4096
     
    int main()
    {
        StructSector _sector;
        int _cpt;
        int _bigcpt;
        printf("Hard disk unitary tests\n");
        /* hard disk creation */
        assert(HW_HARDDISK_Create(HARDDISK_NAME,SECTORS) == 0);
        /* hard disk boot sector verification */
        assert(HW_HARDDISK_ReadSector(HARDDISK_NAME,&_sector,0) == 0);
        assert(_sector.Bytes[3] ==  (SECTORS        & 0xff));
        assert(_sector.Bytes[2] == ((SECTORS >>  8) & 0xff));
        assert(_sector.Bytes[1] == ((SECTORS >> 16) & 0xff));
        assert(_sector.Bytes[0] == ((SECTORS >> 24) & 0xff));
        for(_cpt = 4; _cpt < HW_HARDDISK_SECTOR_SIZE; _cpt++)
        {
            assert (_sector.Bytes[_cpt] == (char)HW_HARDDISK_DEFAULT_BYTE);
        }
        /* hard disk other sectors verification */
        for(_bigcpt = 1; _bigcpt < SECTORS; _bigcpt++)
        {
            assert(HW_HARDDISK_ReadSector(HARDDISK_NAME,&_sector,_bigcpt) == 0);
            for(_cpt = 0; _cpt < HW_HARDDISK_SECTOR_SIZE; _cpt++)
            {
                assert (_sector.Bytes[_cpt] == (char)HW_HARDDISK_DEFAULT_BYTE);
            }
        }
        /* raise error on reading non existing sector */
        assert(HW_HARDDISK_ReadSector(HARDDISK_NAME,&_sector,SECTORS) == 1);
        /* write sector 1 */
        _sector.Bytes[0] = 'P';
        _sector.Bytes[1] = 'F';
        assert(HW_HARDDISK_WriteSector(HARDDISK_NAME,&_sector,1) == 0);
        /* verify boot sector */
        assert(HW_HARDDISK_ReadSector(HARDDISK_NAME,&_sector,0) == 0);
        assert(_sector.Bytes[3] ==  (SECTORS         & 0xff));
        assert(_sector.Bytes[2] == ((SECTORS >>  8)  & 0xff));
        assert(_sector.Bytes[1] == ((SECTORS >> 16 ) & 0xff));
        assert(_sector.Bytes[0] == ((SECTORS >>  24) & 0xff));
        /* verify sector 1 */
        assert(HW_HARDDISK_ReadSector(HARDDISK_NAME,&_sector,1) == 0);
        assert(_sector.Bytes[0] == 'P');
        assert(_sector.Bytes[1] == 'F');
     
        printf("All unit tests successful!\n");
        return 0;
    }

    hw_harddisk.c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
     
    #define HW_HARDDISK_PRIVATE
    #include "hw_harddisk.h"
     
    #include <stdio.h>
     
    int HW_HARDDISK_Create(char* hdname,int sectors)
    {
        int _cpt;
        StructSector _sector;
        StructSector _bootsector;
        FILE* _filestruct;
        int _result;
        for (_cpt = 0; _cpt < HW_HARDDISK_SECTOR_SIZE; _cpt++)
        {
            _sector.Bytes[_cpt] = HW_HARDDISK_DEFAULT_BYTE;
            _bootsector.Bytes[_cpt] = HW_HARDDISK_DEFAULT_BYTE;
        }
        _bootsector.Bytes[3] =  sectors       & 0xff;
        _bootsector.Bytes[2] = (sectors >> 8) & 0xff;
        _bootsector.Bytes[1] = (sectors >> 16)& 0xff;
        _bootsector.Bytes[0] = (sectors >> 24)& 0xff;
     
        if ((_filestruct = fopen(hdname,"wb")) == NULL)
        {
            #ifdef __DEBUG__
                printf("i/o error creating \"%s\"\n",hdname);
            #endif
           return 1;
        }
        fwrite(&_bootsector, sizeof(StructSector), 1, _filestruct);
        sectors--;
        while(sectors--)
        {
            _result = fwrite(&_sector, sizeof(StructSector), 1, _filestruct);
        }
        fclose(_filestruct);
        return 0;
    }
     
    int HW_HARDDISK_ReadSector(char* hdname,StructSector* sector,int sectornum)
    {
        FILE* _filestruct;
        int _result;
        if ((_filestruct = fopen(hdname,"rb")) == NULL)
        {
            #ifdef __DEBUG__
                printf("i/o error opening hard disk \"%s\" on sector %i for read\n",hdname,sectornum);
            #endif
           return 1;
        }
        if (fseek(_filestruct,sectornum * sizeof(StructSector),SEEK_SET))
        {
            #ifdef __DEBUG__
                printf("i/o error seeking sector %i on harddisk \"%s\" for read\n",sectornum,hdname);
            #endif
            fclose(_filestruct);
           return 1;
        }
        _result = fread(sector, sizeof(StructSector), 1, _filestruct);
        if(!_result)
        {
            #ifdef __DEBUG__
                printf("i/o error reading sector %i on harddisk \"%s\"\n",sectornum,hdname);
            #endif
            fclose(_filestruct);
            return 1;
        }
        fclose(_filestruct);
        return 0;
    }
     
    int HW_HARDDISK_WriteSector(char* hdname,StructSector* sector,int sectornum)
    {
        FILE* _filestruct;
        int _result;
        if ((_filestruct = fopen(hdname,"r+")) == NULL)
        {
            #ifdef __DEBUG__
                printf("i/o error opening hard disk \"%s\" on sector %i for write\n",hdname,sectornum);
            #endif
           return 1;
        }
        if (fseek(_filestruct,sectornum * sizeof(StructSector),SEEK_SET))
        {
            #ifdef __DEBUG__
                printf("i/o error seeking sector %i on harddisk \"%s\" for write\n",sectornum,hdname);
            #endif
            fclose(_filestruct);
            return 1;
        }
        _result = fwrite(sector, sizeof(StructSector), 1, _filestruct);
        if(!_result)
        {
            #ifdef __DEBUG__
                printf("i/o error writing sector %i on harddisk \"%s\"\n",sectornum,hdname);
            #endif
            fclose(_filestruct);
            return 1;
        }
        fclose(_filestruct);
        return 0;
    }
    hw_harddisk.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     
    #ifndef HW_HARDDISK_HEADER
     
        #ifndef DATATYPES_HEADER
            #include "datatypes.h"
        #endif
     
        #define HW_HARDDISK_HEADER
     
        #define HW_HARDDISK_SECTOR_SIZE  0x100
        #define HW_HARDDISK_DEFAULT_BYTE 0xff
     
        typedef struct
        {
            char Bytes[HW_HARDDISK_SECTOR_SIZE];
        }StructSector;
     
        #ifdef HW_HARDDISK_PRIVATE
            #define EXTERN
            /* here private declarations and initializations*/
     
        #else
            #define EXTERN extern
            /* here public declarations */
        #endif
     
        /* here all declarations */
     
        EXTERN int HW_HARDDISK_Create(char* hdname,int sectors);
        EXTERN int HW_HARDDISK_ReadSector(char* hdname,StructSector* sector,int sectornum);
        EXTERN int HW_HARDDISK_WriteSector(char* hdname,StructSector* sector,int sectornum);
     
        #ifdef HW_HARDDISK_PRIVATE
            #undef HW_HARDDISK_PRIVATE
        #endif
        #undef EXTERN
     
    #endif

  8. #8
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    947
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 947
    Points : 1 351
    Points
    1 351
    Par défaut
    Salut,

    Bon, c'est résolu, le mode recherché pour écrire en plein milieu d'un fichier est "r+" suivi bien sûr d'un fseek. J'ai édité mes bouts de codes d'en dessus, merci à tous.

    A+

    Pfeuh

  9. #9
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par pfeuh Voir le message
    Bon, c'est résolu, le mode recherché pour écrire en plein milieu d'un fichier est "r+" suivi bien sûr d'un fseek. J'ai édité mes bouts de codes d'en dessus, merci à tous.
    Tu es bien conscient que ce mécanisme écrit pardessus les données existantes, mais n'insère pas. La taille du fichier n'est pas modifiée.

  10. #10
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Pour un disque dur simulé, je pense que c'est bien l'effet voulu.

  11. #11
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    947
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 947
    Points : 1 351
    Points
    1 351
    Par défaut
    Salut,
    Citation Envoyé par Emmanuel Delahaye Voir le message
    Tu es bien conscient que ce mécanisme écrit pardessus les données existantes, mais n'insère pas. La taille du fichier n'est pas modifiée.
    Oui, c'est exactement ce qu'il faut dans ce cas précis.

    A+

    Pfeuh

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. lecture dans un fichier par bloc
    Par danathane dans le forum Langage
    Réponses: 1
    Dernier message: 15/12/2008, 11h02
  2. Lecture de fichier par blocs
    Par nicolas66 dans le forum C++
    Réponses: 12
    Dernier message: 11/11/2006, 20h36
  3. Réponses: 4
    Dernier message: 03/02/2006, 13h50
  4. lecture-ecriture de fichier en mode Random (Get - Put)
    Par MuShRo_Om dans le forum VB 6 et antérieur
    Réponses: 9
    Dernier message: 15/01/2006, 14h53
  5. [SERVLET][JSP] Ecriture de fichier par la servlet
    Par Jabwoo dans le forum Servlets/JSP
    Réponses: 2
    Dernier message: 15/07/2004, 17h57

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo