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

Langage Delphi Discussion :

Insérer des octets dans un fichier


Sujet :

Langage Delphi

  1. #1
    Membre actif

    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    310
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 310
    Points : 208
    Points
    208
    Par défaut Insérer des octets dans un fichier
    Bonjour à tous,

    J'utilise la classe Tfilestream pour lire et remplacer des données dans un fichier. J'aimerai insérer des octets au début d'un fichier, en fait je veux remplacer un header de 64 octets par un autre de 128 octets donc je pensais insérer 64 octets et remplacer les 64 suivants. Si j'utilise la méthode Write, ça me remplace uniquement les octets par des autres, ça n'insère rien et écrase des données que je veux conserver.

    Comment faire?

    Merci d'avance

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    L'insertion c'est le plus problématique, car cela implique de décaler tout le reste ...

    Ouvre deux FileStream, un sur la source, l'autre sur la destination, puis génère ton entête dans le stream destination, puis ensuite, tu boucles bêtement pour copier la source dans la destination (fait le par un buffer de 64Ko par exemple, pour avoir une progression sans avoir trop de lenteur)

    Ensuite, sauvegarde l'original ailleurs, et renomme le fichier de destination ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre actif

    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    310
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 310
    Points : 208
    Points
    208
    Par défaut
    Merci
    J'avais pensé à cette méthode mais je m'étais dit qu'il y avait une autre classe faites pour les insertions.

    A propos du buffer de 64 ko, je n'ai aucune idée de comment m'y prendre. Est ce qu'il faut que je crée une variable temporaire et que je concatene chaque octet lu et que j'écrive dès que j'en ai 65536 ?

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Bon, l'idée est là, la syntaxe c'est pas tout à fait ça ... Donc tu lit, les 64Ko d'un coup, et tu les écrits d'un coup, tu as toutes les fonctions pour, et heureusement c'est nettement plus rapide en lecture DD et allocation mémoire des buffers que la concaténation ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    var
      InStream: TFileStream;  
      OutStream: TFileStream;
      Header: array[0..127] of Byte; // Tu peux faire aussi un packed record de 128 octets, j'ai mis bcp d'exemple sur le forum à ce sujet
      Buffer: array[Word] of Byte;
    begin
      BuildHeader(Header);
      OutStream.Write(Header, SizeOf(Header)); 
    
      InStream.Read(Buffer, SizeOf(Buffer)); // Peut-être un @Buffer...
      OutStream.Write(Buffer, SizeOf(Buffer)); 
    end;
    Un petit appel à ceux qui connaisse NTFS (darkvadr par exemple) pour voir si l'insertion de données en possible via une fragmentation du fichier ?
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Membre actif

    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    310
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 310
    Points : 208
    Points
    208
    Par défaut
    C'est carrément plus rapide avec un buffer, surtout sur un fichier volumineux. J'ai fait le test sur un fichier de 70 mo avec et sans buffer et je gagne plusieurs minutes avec le buffer
    Merci beaucoup

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    160
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 160
    Points : 167
    Points
    167
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Un petit appel à ceux qui connaisse NTFS (darkvadr par exemple) pour voir si l'insertion de données en possible via une fragmentation du fichier ?
    Oulala, il y a longtemps que je n'ai rien posté. Ca crain...
    Dire que je connais NTFS est un peu exagéré disons que mon ancien boulot faisait que j'étais obligé de m'y interesser.

    Et ca fait plus d'un an que j'ai changé de job, il faudrait que je me replonge dedans, mais pour être honnête mon nouveau boss est un esclavagiste et je n'ai que peu de temps.

    Si j'ai bien comprit l'idée qui se cache dans ton cerveau shaï voici schématiquement ce que tu voudrais réaliser:

    soit un fichier représenté comme ca...

    disons:

    xxxxxxxxxxxxxx

    et le données à insérer

    yyyy

    ou chaque x et chaque y est un octet.

    Voici par exemple le resultat qu'on veut obtenir après insertion

    xxxxxyyyyxxxxxxxxx

    ce qui oblige a faire des décallages.

    Mais mais dans ton cerveau aussi malade que le mien tu te dis sans doute

    pourquoi ne pas l'écrire comme ca:

    xxxxxxxxxxxxxxyyyy

    et aller trafiquer la table d'alloc pour dire: Voici un fichier fragmenté!
    et il faut le lire comme sur l'image jointe (par exemple et grosso modo)

    mmmmmm.... pas simple du tout... mais réalisable... il faudrait que j'y réfléchisse.

    Ce serait un hack intéressant... Comment utiliser un problème conceptuel (la fragmentation) pour optimiser une insertion...
    Images attachées Images attachées  

  7. #7
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Exactement, DarkVadr, les esprits malades se rencontrent ... mais c'était l'idée, après cela améliore l'insertion si le volume de données est important après la dite insertion, mais à voir si en lecture, si faire balader les têtes de lecture ne détériore pas trop les performances en faisant perdre très vite le gain de l'insertion, ...

    Comment font les DB, je sais qu'en paradox, les insertions dans la clé primaire c'est la cata car justement ça décale car l'ordre physique c'est la clé primaire justement ... dans les autres DB, j'ignore comment c'est fait ... mais il me semble plus performant d'avoir un index que l'on met à jour qui indique la position des enregistrements (sauf si l'enreg est plus petit que la table d'index), ces derniers étant écrit dans un ordre peu important (surtout pour la problématique des VarChar ...),
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    160
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 160
    Points : 167
    Points
    167
    Par défaut vers la fin d'un reve...
    Citation Envoyé par ShaiLeTroll Voir le message
    Exactement, DarkVadr, les esprits malades se rencontrent ... mais c'était l'idée, après cela améliore l'insertion si le volume de données est important après la dite insertion, mais à voir si en lecture, si faire balader les têtes de lecture ne détériore pas trop les performances en faisant perdre très vite le gain de l'insertion, ...

    Comment font les DB, je sais qu'en paradox, les insertions dans la clé primaire c'est la cata car justement ça décale car l'ordre physique c'est la clé primaire justement ... dans les autres DB, j'ignore comment c'est fait ... mais il me semble plus performant d'avoir un index que l'on met à jour qui indique la position des enregistrements (sauf si l'enreg est plus petit que la table d'index), ces derniers étant écrit dans un ordre peu important (surtout pour la problématique des VarChar ...),
    Pour répondre, faire balader les têtes en lecture ne serait pas vraiment problématique si on reste dans les limites du raisonnable. En fait dans le cas d'un gros fichier il n'y aurait que des avantages puisque
    1) l'insertion serait extrêmement rapide.
    2) tout bon professionnel laisse tourner un défragmenteur de temps à autre.

    J'ai plein d'arguments mais, mais, mais... Je suis obligé de ternir le tableau.

    Passant outre le fait qu'attaquer directement la mft est relativement dangereux pour la stabilité du système et pour les données (du moins en période de debuggage),j'ai commencé a travaillé un peu sur la fragmentation quand tout à coup...

    Arrrrrggg.

    NTFS fragmente par cluster!
    Typiquement 8*512 bytes.

    Or ici on parle d'insertion.

    Comme il est peu probable d'avoir justement n blocs de 8*512 bytes (pile poil) à insérer ça devient pour le moins illusoire.

    On se retrouve avec une insertion contenant ce qu'il faut nommer de la merde au bout.

    Il faut non seulement attaquer la mft (ce qui devient vite galère si le fichier est déjà "naturellement" fragmenté), mais il faut en plus prévoir un format de fichier complexe spécifique à cette utilisation avec padding et un parser.

    le bloc à insérer pourrait ressembler à ça.

    [yyyyyyyy][i i zzzz][FF FF FF ...FF FF]



    [yyyyyyyy] sont les bytes à insérer



    [i i zzzz] est un bloc avec une instruction disant fin de lecture codée (arbitrairement pour l'exemple sur deux octets)... ici on dira que c'est i i et zzzz serait l'offset du prochain bloc de données valide.

    du coup

    [FF FF FF ...FF FF] représente soit un padding pour faire propre, soit directement l'infâme bouillie sortie directement du cloaque de notre hdd... Peu importe ce bloc sera sauté.

    Mais là, il faut réfléchir attentivement aux gains espérés versus la complexité du problème et les défauts identifiables:

    -Maitriser la mft
    -Fichier spécifique a ce genre d'utilisation
    -Donc gestion du format de fichier plus lourde
    -ET fichiers plus lourd avec beaucoup de place perdue
    -Fichtrement lié (à bas niveau) a NTFS qui est propriétaire Microsoft tm, peu et approximativement documentée grace au reverse Engineering (avec les drivers ntfs-3g linux on arrive quand même a s'y retrouver). Quid si microsoft change quelque chose?

    bref bref bref

    mais il me semble plus performant d'avoir un index que l'on met à jour qui indique la position des enregistrements
    Oui.

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

Discussions similaires

  1. Insérer des données dans un fichier txt existant
    Par ED2912 dans le forum MATLAB
    Réponses: 7
    Dernier message: 08/09/2011, 17h04
  2. écrire et lire des octets dans un fichier
    Par toutounesan dans le forum VB.NET
    Réponses: 3
    Dernier message: 23/06/2011, 10h52
  3. Réponses: 1
    Dernier message: 20/06/2011, 17h35
  4. [CSV] Insérer des champs dans un fichier CSV
    Par floctc dans le forum Langage
    Réponses: 1
    Dernier message: 20/07/2009, 11h26
  5. Lire des octets dans un fichier binaire
    Par DiverSIG dans le forum Entrée/Sortie
    Réponses: 12
    Dernier message: 19/01/2009, 10h22

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