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

Lazarus Pascal Discussion :

Effectuer une copie de fichier [Lazarus]


Sujet :

Lazarus Pascal

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Retraité
    Inscrit en
    Juillet 2008
    Messages
    390
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Juillet 2008
    Messages : 390
    Par défaut Effectuer une copie de fichier
    Bonjour,
    J'ai trouvé dans la FAQ Lazarus un petit programme de WILE 64 qui permet de copier un fichier avec la visualisation de l'avancement par une barre de progression.
    Je l'utilise depuis un certain temps sous Linux et tout fonctionne bien. Je n'utilise pas la barre de progression car la copie que je demande pour sauvegarder un fichier est très rapide.
    Mais pour une petite application qui doit tourner sous XP j'ai compilé mon appli sous lazarus 09.28.2 sous XP, tout fonctionne à l'adaptation des chemins d'accès aux fichiers, sauf la copie de sauvegarde. Quelqu'un pourrait-il m'aider ?
    Précision la copie concerne une petite base SQLITE.
    Le message d'erreur aussi Unable to open file suivi du chemin et nom du fichier à copier.
    Merci d'avance

  2. #2
    Membre Expert
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 46

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Par défaut
    et le code ?
    [ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
    Ma messagerie n'est pas la succursale du forum... merci!

  3. #3
    Membre éclairé
    Homme Profil pro
    Retraité
    Inscrit en
    Juillet 2008
    Messages
    390
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Juillet 2008
    Messages : 390
    Par défaut
    Voici le code brut car pour essayer de comprendre j'ai écris une petit module

    la partie préparation et l'appel à la procédure issue de la FAQ
    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
    procedure TFsauve.Prepare;
    begin
    MFUTURE:=MDESTINATION;
    Edit5.Text:=MFUTURE;
    MCHEMIN:=divers.FieldByName('REPERTOIRE').AsString;
    Edit1.Text:=MCHEMIN;
    MBASE:='BIBLIO.sdb';
    Edit4.Text:=MBASE;
    MSOURCE:=MCHEMIN+'tables/'+MBASE;
    Edit2.Text:=MSOURCE;
    MDESTINATION:=MCHEMIN+MFUTURE+MBASE;
    Edit3.Text:=MDESTINATION;
    Edit6.Text:=MSAUVE_X;
    Update;
    end;
     
    procedure TFsauve.BCopieClick(Sender: TObject);
    begin
     MMODIFICATION:='OUI';
      if MMODIFICATION='OUI' then
      begin
      Q1:=quotedstr(MSAUVE_X);
      MQ:='update divers set SAUVE_X='+Q1+' where K_DIVERS=1';
      divers.SQL:=MQ;
      divers.ExecSQL;
      divers.ApplyUpdates;
      CopierFichier (MSOURCE,MDESTINATION);
      divers.Close;
      MQ:='select * from divers';
      divers.SQL:=MQ;
      divers.Open;
      divers.ExecSQL;
      MSAUVE_X:=divers.FieldByName('SAUVE_X').AsString;
      Edit6.Text:=MSAUVE_X;
      Edit6.Update;
      end
      else Close;
    end;
    et maintenant la procédure légèrement modifiée

    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
    Procedure CopierFichier (Source, Destination : String);
    Var
      Src, Dst : TStream;
      i, Count : Int64;
      buffer : Array [0..1023] of Byte;
    Begin
        // Ouvrir le fichier source
        Src := TFileStream.Create(Source,fmOpenRead);
        // Ouvrir le fichier destination
        Dst := TFileStream.Create(Destination,fmcreate or fmOpenWrite);
        // Source au début de fichier
        Src.Position := 0;
        // Taille du fichier
        Count := Src.Size;
        // Début de la copie
        while Count > 0 do
          begin
            // On suit la progression de 0 à 100 %
            //ProgressBar1.Position := trunc(100.0 * (Src.position / Src.size));
            // Traitement des messages pour ne pas bloquer tout le système
            //Application.ProcessMessages;
            // Si count + grand que buffer on lit la taille du buffer
            if (Count > sizeof(buffer)) then i := sizeof(Buffer)
               else i:=Count;
            // On lit i bits
            i := Src.Read(buffer,i);
            // On écrit i bits
            i := Dst.Write(buffer,i);
           // Si i = 0 plus rien à copier ou erreur
            if i = 0 then break;
            dec(count,i);
          end;
        // Libération des streams
        Src.Free;
        Dst.Free;
        //Close;
    end;
    Je le répète elle fonctionne sous linux (fedore) avec lazarus 0.9.29 du 16/12/2009 et pour XP c'est la version 0.9.28.2

    Petite précision, le message indique sauf mauvaise traduction de ma part que la base ne peut être ouverte pourtant j'affiche correctement les données dans des DBGrid.
    A+

  4. #4
    Membre Expert
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 46

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    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
    function StreamCopyFile(const SrcFile, DestFile : String; const CopySize: LongInt= 65535): boolean;
    var
      Src, Dst : TFileStream;
      W        : Int64;
    begin
      result := false;
     
      assert(fileExists(SrcFile), 'Source file not exists');
      assert(SrcFile <> DestFile, 'Source and destination file must be different!');
      assert(not fileExists(DestFile), 'Destination file already exists!');
     
      Src := TFileStream.Create(SrcFile, fmOpenRead);
      try
        Dst := TFileStream.Create(DestFile, fmCreate);
        try
          repeat
            W := Dst.CopyFrom(Src, CopySize);
          until W < CopySize;
          result := Src.Size = Dst.Size;
        finally
          Dst.Free;
        end;
      finally
        Src.Free;
      end;
    end;

    sinon il y à la fonction CopyFile qui existe sur Windows et Linux.
    [ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
    Ma messagerie n'est pas la succursale du forum... merci!

  5. #5
    Membre éclairé
    Homme Profil pro
    Retraité
    Inscrit en
    Juillet 2008
    Messages
    390
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Juillet 2008
    Messages : 390
    Par défaut
    Merci Dr.Who

    pour ta réponse mais comme j'aime comprendre, j'ai refait d'autres essais et je me suis aperçu qu'à la compilation sous XP j'avais une message d'anomalie non bloquant.
    Le message 'Hint : local variable "buffer" does not seem to be initialised'
    Chose étrange puisque cette variable est déclarée en début de procédure, peut-être faut-il sous windows ajouter une unité dans la déclaration pour prendre en compte les "tableaux" mais je ne sais pas laquelle si c'est le problème.
    A suivre ?

  6. #6
    Membre Expert
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 46

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Par défaut
    la méthode que tu utilise est déjà mauvaise dans l'ensemble.
    alors ... à toi de voir ...

    en plus je pense que :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    divers.ApplyUpdates;
      CopierFichier (MSOURCE,MDESTINATION);
      divers.Close;
    vus que la base n'est pas fermée, le fichier pourrait être "occupé" et donc si l'ouverture est bloquante (not shared read), on ne pourra pas ouvrir de stream dessus.


    TFileStream! pourquoi utiliser l'ancêtre ? c'est du n'importe quoi, ça bloque l'autocompletion et l'aide, bref à part embetter le developpeur ça sert à rien, surtout dans ce genre d'utilisation.
    et aux gens qui dirons que c'est mieux comme ça je repond, autant faire :

    et encore mieux :


    donc, merci bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Src, Dst : TFileStream;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    buffer : Array [0..1023] of Byte;
    ouai pourquoi pas ... tant qu'on as pas plus de 100Mo à copier.
    mais bon, copyFrom c'est pas fait que pour les VBistes, de plus avec CopyFrom, pas besoin de buffer.



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      // Ouvrir le fichier destination
    Dst := TFileStream.Create(Destination,fmcreate or fmOpenWrite);
    fmOpenWrite inutile, on fait une copie 1:1 du fichier source donc fmCreate paf.



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    // Source au début de fichier
        Src.Position := 0;
    on etait déjà au début du flux ...


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     // Taille du fichier
        Count := Src.Size;
    ça par contre un grand OUI! toujours mettre en cache les propriétés qui appelent souvent des fonctions longue d'execution et ralentisse les boucles.



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    // Début de la copie
        while Count > 0 do
          begin
    dés qu'on parle de Stream, si un while apparait, à tout coups la méthode est mauvaise.

    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
          // Si count + grand que buffer on lit la taille du buffer
            if (Count > sizeof(buffer)) then i := sizeof(Buffer)
               else i:=Count;
            // On lit i bits
            i := Src.Read(buffer,i);
            // On écrit i bits
            i := Dst.Write(buffer,i);
           // Si i = 0 plus rien à copier ou erreur
            if i = 0 then break;
            dec(count,i);
        // Libération des streams
        Src.Free;
        Dst.Free;
        //Close;
    end;
    la c'est du grand n'importe quoi.
    méthode compliqué et lourde pour une simple copie de flux à flux.
    pas de try finally pour s'assurer que les flux soit bien fermés et que l'accés aux fichiers ne soient pas bloqués.
    bef du début à la fin ... c'est tout bidon...


    bon, c'est bien de vouloir comprendre ... mais vouloir comprendre une méthode qui n'est pas bonne ... c'est une perte de temps.

    utilise ma correction ou la fonction CopyFile.
    [ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
    Ma messagerie n'est pas la succursale du forum... merci!

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 02/05/2007, 08h20
  2. Réponses: 2
    Dernier message: 22/03/2007, 13h25
  3. Forte charge du système lors d'une copie de fichiers
    Par calfater dans le forum Administration système
    Réponses: 5
    Dernier message: 08/01/2007, 17h52
  4. Problème pour faire une copie de fichier.
    Par damien99 dans le forum C++
    Réponses: 1
    Dernier message: 12/02/2006, 16h37
  5. Réponses: 3
    Dernier message: 19/10/2005, 15h58

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