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 :

écrire au début d'un fichier


Sujet :

C

  1. #1
    Nouveau membre du Club
    Inscrit en
    Février 2008
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 42
    Points : 30
    Points
    30
    Par défaut écrire au début d'un fichier
    En C, est-ce qu’il existe un moyen d’écrire dans un fichier existant, en ajoutant les données en début de fichier ?

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    Ajouter, non. Tu ne peux ajouter des caractères qu'à partir de la fin.
    Si tu remontes plus haut dans le fichier, tu peux seulement remplacer les caractères existants par d'autres.

    Si tu veux insérer des caractères, tu ne peux pas faire autrement que écrire dans un second fichier, effacer le premier puis renommer le second avec le nom du premier.

  3. #3
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2011
    Messages
    1 186
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 186
    Points : 2 502
    Points
    2 502
    Par défaut
    Bonsoir,

    Solution sans passer par un fichier intermédiaire, et si la taille du fichier le permet :
    - Ouvrir le fichier en R/W
    - Lire tous le fichier dans un tableau d'octet en mémoire.
    - Replacer le pointeur de fichier en début de fichier.
    - Ecrire les nouveaux octets dans le fichier,
    - Ecrire le tableau d'octet relu précédemment.
    - Fermer le fichier.

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 369
    Points : 23 623
    Points
    23 623
    Par défaut
    Citation Envoyé par BlueMonkey Voir le message
    Bonsoir, Solution sans passer par un fichier intermédiaire, et si la taille du fichier le permet :
    - Ouvrir le fichier en R/W
    - Lire tous le fichier dans un tableau d'octet en mémoire.
    - Replacer le pointeur de fichier en début de fichier.
    - Ecrire les nouveaux octets dans le fichier,
    - Ecrire le tableau d'octet relu précédemment.
    - Fermer le fichier.
    Attention, si le fichier intermédiaire est souvent le plus efficace en temps normal, cela n'est pas sans impact sur le système de fichier : par exemple, il peut être impossible d'obtenir à la création du fichier temporaire les droits d'accès accordés au fichier source. Pire, si le droit d'écriture est accordé sur le fichier source, il peut être néanmoins impossible de le supprimer, par exemple (sous Unix) à cause d'un sticky bit ou tout simplement parce qu'on n'a pas les droits d'écriture sur le répertoire qui le contient. Et tout cela est encore plus vrai si le système de fichiers est distant, à travers le réseau.

    En outre, si le fichier est très gros, le fichier temporaire peut l'être aussi. Si on souhaite ajouter des informations au début d'un fichier de 2 Go, créer un fichier temporaire de 2 Go lui-aussi peut ne pas être possible du tout.

  5. #5
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 936
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 936
    Points : 4 356
    Points
    4 356
    Par défaut
    Citation Envoyé par BlueMonkey Voir le message
    Bonsoir,

    Solution sans passer par un fichier intermédiaire, et si la taille du fichier le permet :
    - Ouvrir le fichier en R/W
    - Lire tous le fichier dans un tableau d'octet en mémoire.
    - Replacer le pointeur de fichier en début de fichier.
    - Ecrire les nouveaux octets dans le fichier,
    - Ecrire le tableau d'octet relu précédemment.
    - Fermer le fichier.
    si la taille dépasse ce que l'on tolère d'allouer comme buffer de travail, cette opération de réécriture peut toujours être effectué par "chunk" en partant de la fin du fichier et en "remontant" vers le point d'insertion désiré (si on généralise : le cas "au début" n'étant qu'un cas particulier où l'offset du point d'insertion = 0…)

    la seule condition est que le système de fichiers qui héberge le document supporte le "seek" en général et le "seek" au-delà de la fin du fichier en particulier…
    (ce n'est pas toujours le cas d'un système de fichiers en réseau par exemple)

  6. #6
    Membre expérimenté

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Points : 1 418
    Points
    1 418
    Par défaut
    Bonjour,

    je penses que tu peux écrire en début de fichier existant sans écraser le reste, mais on pourra me contredire si je me trompe, je n'ai pas essayé :

    -tu ouvres ton fichier à partir des appels systèmes comme open (man open) en utilisant les flags O_RDWR et O_TRUNC (l'équivalent d'un "a+" avec fopen je penses)

    - tu te déplace en début de fichier avec seek (man lseek), en utilisant la directive whence SEEK_SET et un offset à 0.

    -bah ensuite t'as plus qu'à ajouter tes données.


    Mais en y réfléchissant il y a de grandes chances que cela écrase les données existantes, mais après tu peux toujours décaler tes données au fur et à mesure, ce qui sera lourd (du coup la copie des données dans un fichier ou un tableau avant de les "ré-ajouter" après insertion des nouvelles données semble le mieux). Mais ce que j'ai proposé est à tester, peut-être que rien ne sera effacé.


    Cordialement,
    Nullius in verba

  7. #7
    Membre averti Avatar de hariman
    Homme Profil pro
    Développeur Java, Android
    Inscrit en
    Janvier 2008
    Messages
    200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Ile Maurice

    Informations professionnelles :
    Activité : Développeur Java, Android
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2008
    Messages : 200
    Points : 413
    Points
    413
    Par défaut
    Bonjour,

    J'ai déjà essayé la méthode de Kaamui autrefois et effectivement cela écrase les données existantes.

    Qu'en pensez-vous de cette méthode-ci :

    - créer un nouveau fichier (ex : fic2) et l'ouvrir en W
    - y écrire les données à ajouter en premier
    - ouvrir le fichier qui nous intéresse (ex : fic1) en R
    - ecrire dans fic2 chaque caractère lu dans fic1
    - fermer les 2 fichiers
    - supprimer fic1 (puisqu'on a le résultat dans fic2)
    - renommer fic2 en fic1 (si besoin)

    Question performance :
    Mais cela retombe au même principe que si on veut ajouter des données au début du fichier, il faut décaler tous les anciens données.
    Les boutons et adorent être cliqués, donc ne les oubliez pas

  8. #8
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 936
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 936
    Points : 4 356
    Points
    4 356
    Par défaut
    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
     
    input: fileDescriptor (opened in RW), insertPosition, dataToInsert, dataToInsertSize
     
    assert: fileDescriptor is valid and seek-able
    assert: insertPosition >= 0
    assert: dataToInsert != nil
    assert: dataToInsertSize > 0
     
    # better if tempBufferSize is multiple of disk sector size, take even multiple of 1024 if you don't know
    tempBufferSize <- TO_BE_DEFINED
     
    alloc tempBuffer of tempBufferSize 
    fileSize <- seek fileDescriptor to EOF
    readPosition <- fileSize - tempBufferSize
    writePosition <- fileSize + dataToInsertSize - tempBufferSize
     
    while readPosition > insertPosition
        seek file to readPosition
        read tempBufferSize bytes from file into tempBuffer
        seek to writePosition 
        write tempBufferSize bytes into file from tempBuffer
        readPosition -= tempBufferSize
        writePosition -= tempBufferSize
    end while
     
    # at this point readPosition is before insertPosition but may be negative
    # and you still have to move the remaining chunk of bytes from insertPosition to readPosition + tempBufferSize (the latest readPosition before it becomes < insertPosition)
     
    # the "special" case readPosition == insertPosition at the end of the loop is eventually not special at all...
    # in that case, the maths involved here below will correctly move tempBufferSize bytes from insertPosition to the correct writePosition
    seek fileDescriptor to insertPosition
    read (readPosition + tempBufferSize - insertPosition) bytes from fileDescriptor into tempBuffer
    # next write position is (writePosition + tempBufferSize) - (readPosition + tempBufferSize - insertPosition)
    # thus after simplification…
    seek fileDescriptor to (writePosition - readPosition + insertPosition)
    write (readPosition + tempBufferSize - insertPosition) bytes into fileDescriptor from tempBuffer
     
    # now actually write the data to be inserted
    seek fileDescriptor to insertPosition
    write dataToInsertSize bytes into fileDescriptor from dataToInsert
     
    free tempBuffer

  9. #9
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 369
    Points : 23 623
    Points
    23 623
    Par défaut
    Citation Envoyé par hariman Voir le message
    Qu'en pensez-vous de cette méthode-ci :
    J'en pense que c'est la méthode qui a été proposée dès le commentaire numéro 2 et qu'elle a toujours les inconvénients cités au numéro 4.

  10. #10
    Membre averti Avatar de hariman
    Homme Profil pro
    Développeur Java, Android
    Inscrit en
    Janvier 2008
    Messages
    200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Ile Maurice

    Informations professionnelles :
    Activité : Développeur Java, Android
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2008
    Messages : 200
    Points : 413
    Points
    413
    Par défaut
    j'ai lu les commentaires en diagonale ! désolé
    Les boutons et adorent être cliqués, donc ne les oubliez pas

  11. #11
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 685
    Points : 30 974
    Points
    30 974
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Kaamui Voir le message
    Bonjour,
    Bonjour

    Citation Envoyé par Kaamui Voir le message
    je penses que tu peux écrire en début de fichier existant sans écraser le reste, mais on pourra me contredire si je me trompe, je n'ai pas essayé :
    Ben le minimum c'est d'essayer tes exemples avant de venir les poser en solution sur un forum...

    Citation Envoyé par Kaamui Voir le message
    -tu ouvres ton fichier à partir des appels systèmes comme open (man open) en utilisant les flags O_RDWR et O_TRUNC (l'équivalent d'un "a+" avec fopen je penses)
    Non. O_RDWR signifie "read+write" => cela signifie que tu veux à la fois lire et écrire dans le fichier. O_TRUNC signifie "troncature" => le fichier est vidé à l'ouverture. Donc en fait rien à voir avec "ouverture en mode append" qui se fait en utilisant le flag O_APPEND !!! Un autre minimum c'est de lire les liens que tu donnes...

    Citation Envoyé par Kaamui Voir le message
    - tu te déplace en début de fichier avec seek (man lseek), en utilisant la directive whence SEEK_SET et un offset à 0.

    -bah ensuite t'as plus qu'à ajouter tes données.
    Et donc en écrivant au début du fichier tu n'as pas l'impression d'écraser les données qui y sont ??? Ah ben non elles n'y sont plus vu que le fichier a été ouvert en mode O_TRUNC...

    Citation Envoyé par Kaamui Voir le message
    Mais en y réfléchissant
    Ah !!! Enfin !!!

    Citation Envoyé par Kaamui Voir le message
    Mais ce que j'ai proposé est à tester, peut-être que rien ne sera effacé.
    Ben pourquoi tu n'as pas testé toi-même ??? Ca prend 20 lignes à taper (en y incluant les commentaires)...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. écrire au début d'un fichier
    Par haskouse dans le forum Développement de jobs
    Réponses: 1
    Dernier message: 08/03/2013, 09h24
  2. Réponses: 10
    Dernier message: 23/09/2010, 16h42
  3. écrire au début d'un fichier
    Par luna007 dans le forum Entrée/Sortie
    Réponses: 6
    Dernier message: 01/09/2009, 16h30
  4. Écrire au début du fichier
    Par Nayila dans le forum Langage
    Réponses: 4
    Dernier message: 26/10/2008, 09h14
  5. écrire au début d'un fichier sans l'écraser
    Par Davboc dans le forum Langage
    Réponses: 11
    Dernier message: 30/12/2005, 01h48

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