Page 2 of 3 FirstFirst 1 2 3 LastLast
Results 16 to 30 of 35

Thread: Plaatjes kopieeren in nog aan te maken mappen

  1. #16
    mov rax,marcov; push rax marcov's Avatar
    Join Date
    Apr 2004
    Location
    Ehv, Nl
    Posts
    10,357
    Dus de directory is gemuteerd. Als het OS besluit de directory op te schonen (dode entries te verwijderen, b.v. omdat de file die je moved de laatste bezette node is in dat blok) ben je dus nat als files die je NOG moet doen verplaatsen naar een blok dat je al gedaan hebt.

    Op *nix weet ik zeker dat de hele dir niet van te voren ingelezen word, dat gaat stapsgewijs.

  2. #17
    Quote Originally Posted by marcov View Post
    Dus de directory is gemuteerd. Als het OS besluit de directory op te schonen (dode entries te verwijderen, b.v. omdat de file die je moved de laatste bezette node is in dat blok) ben je dus nat als files die je NOG moet doen verplaatsen naar een blok dat je al gedaan hebt.
    Ik ga ervan uit dat een OS dat goed regelt bij een findnext. Zoniet dan zijn dus ALLE programma's die findnext gebruiken potentieel buggie. Want dan zou het verwijderen van de eerste file uit de directory tijdens een findnext dus altijd voor problemen zorgen... ook bij "dir" en "ls".

    Op *nix weet ik zeker dat de hele dir niet van te voren ingelezen word, dat gaat stapsgewijs.
    Je zou bij findnext op zich moeten controleren of de file nog bestaat maar een robuust filesystem zal toch zo opgezet zijn dat als je een findnext loop doet dat alle files doorlopen worden.

    Of heb jij documentatie van het tegenovergestelde?

  3. #18
    If somebody creates or deletes a file in a directory while I am enumerating its contents, what happens?

    Dus volgens mij worden alle files die in de directory staan afgelopen.

    What you can say is that files which were neither created nor deleted during the enumeration will be enumerated.
    Dus ook als je de net gevonden files met findnext naar een andere directory swiept.

    Ik ga er even vanuit dat andere OSen ook zo'n robuust filesystem hebben.

  4. #19
    mov rax,marcov; push rax marcov's Avatar
    Join Date
    Apr 2004
    Location
    Ehv, Nl
    Posts
    10,357
    Quote Originally Posted by rvk View Post
    Ik ga ervan uit dat een OS dat goed regelt bij een findnext. Zoniet dan zijn dus ALLE programma's die findnext gebruiken potentieel buggie. Want dan zou het verwijderen van de eerste file uit de directory tijdens een findnext dus altijd voor problemen zorgen... ook bij "dir" en "ls".
    Ik weet het niet zeker. Mogelijk alloceert *nix nieuwe inodes voor de rewritten directory, en blijven de oude inodes bestaan tot de laatste handle erna dood is. Dat is een beetje de filosofie van *nix filesystems.

    Ik zou er echter niet op gokken.

  5. #20
    Ja, maar dat risico zou je dan met findallfiles in een tstringlist lezen in principe ook hebben op een druk filesystem met meerdere gebruikers. Ik heb er echt nog nooit van gehoord dat dat dan een probleem zou zijn. Findfirst/next combinatie mag op een filesystem nooit dubbele entries geven of loopen o.i.d. Het kan nieuwe files niet zien of verwijderde files weergeven, maar meer problemen zou ik niet verwachten.

    Ik durf daar wel op te gokken

  6. #21
    Wel Rik, je code werkt enorm goed, en heel snel.

    Toch loop ik tegen een heel klein probleempje op, als ik later nog wat plaatjes vind, en wil dat toevoegen middels dit programma dan gebeurt er niets.
    Voorbeeld, in alle mappen staan 2500 plaatjes, behalve in de laatste, daar staan er maar 900, in principe zou deze dus aangevuld moeten worden.
    Welke functie moet ik daar voor hebben?

    In ieder geval het grootste werk is in ieder geval gedaan, dat scheelt heel veel drag and drop acties.

    Dank je wel

  7. #22
    Quote Originally Posted by WillemS View Post
    Toch loop ik tegen een heel klein probleempje op, als ik later nog wat plaatjes vind, en wil dat toevoegen middels dit programma dan gebeurt er niets.
    Uh, jawel, volgens mij gebeurd er dan wel wat.
    Ik denk dat de plaatjes die in de base van die directory staan dan gewoon weer naar directory 001 verplaatst worden, ongeacht dat er daar al 1000 in staan.

    Als je dit al geprobeerd hebt dan heb je nu in 001 waarschijnlijk meer dan 1000 files staan.

    Wil je dit oplossen dan zul je de Counter :=0 aan moeten passen. Als je er vanuit gaat dat er in 001, 002, 003 etc 1000 files zitten dan moet je eerst kijken wat de laatste directory is. Is die bijvoorbeeld 012, dan heb je al 11x1000 files in 001, 002 etc zitten en een bepaald aantal in 012. Zet de counter dan op 11000+het aantal dat in 012 zit. Op die manier begint de counter bijvoorbeeld bij 11234 en worden er nooit meer dan 1000 files in die 012 gezet en wordt daarna dus gelijk weer de 013 aangemaakt.

    Let op, als je meer dan 1.000.000 files verwacht zul je met 4 cijfers moeten werken (dus 0001, 0002 etc).

  8. #23
    Beste Rik,

    Ik heb hem afgelopen nacht laten draaien, zodat hij alle tijd had om de laatste file aan te maken, of alles in een aparte directory te plaatsen.
    Helaas bij het wakker worden was er niets gewijzigd.
    Het aantal van 2500 bestanden is ongewijzigd, het aanmaken van extra mappen, dus niet.

    De laatste map dat was aangemaakt was 068 met daarin 900 bestanden.
    Nu vraag ik mij af, of de laatste directory niet via een spinedit aan te geven is als start van een nieuwe sessie

    Willem

  9. #24
    En hoeveel bestanden staan er nu in 001?

    Ik kan er eigenlijk verder weinig over zeggen zonder je code te zien.

    Je probleem zover ik het nu begrijp is dat je al een directory van 001 tot 068 hebt.
    In 001 zitten dan 1000 bestanden, in 002 zitten 1000 bestanden enzovoort... en in 068 zitten 900 bestanden.
    Verder je in de root van die directory ook nog eens los 2500 bestanden staan die je nu verder wilt verdelen over 068, 069 enzovoort.
    Begrijp ik dat goed?

    Zo ja, dan moet je nu even de code laten zien die je nu gebruikt.

  10. #25
    De code is nog redelijk standaard, zoals je ziet.
    Wat heb ik zelf allemaal ondernomen, wel als eerste heb ik het aantal files in de map naar 2500 gebracht.
    Het tweede wat ik heb geprobeerd is het wijzigen van de targetdirectory, maar wat ik ook probeer hij blijft in de map plaatsen van waar alle bestanden zijn, maar dat is niet echt een groot probleem.

    Wat voor mij redelijk een functionele functie zou zijn is om bij het toevoegen van bestanden, bij de laatste map wordt door gegaan tot ook die wordt aangevuld tot 2500.
    Zelf had ik het idee omdat via een spinedit te doen, ik ben er achter gekomen dat dit het werk is van de functie inc (doet het optellen, als ik het goed begrepen heb).


    1
    Delphi Code:
    1. unit MFB;
    2.  
    3. {$mode objfpc}{$H+}
    4.  
    5. interface
    6.  
    7. uses
    8.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
    9.  
    10. type
    11.  
    12.   { TForm1 }
    13.  
    14.   TForm1 = class(TForm)
    15.     Button1: TButton;
    16.     procedure Button1Click(Sender: TObject);
    17.   private
    18.     { private declarations }
    19.   public
    20.     { public declarations }
    21.   end;
    22.  
    23. var
    24.   Form1: TForm1;
    25.  
    26. implementation
    27.  
    28. {$R *.lfm}
    29.  
    30. { TForm1 }
    31.  
    32. procedure TForm1.Button1Click(Sender: TObject);
    33. var
    34.   Counter: integer;
    35.   BaseDirectory, TargetDirectory: string;
    36.   SearchRec: TSearchRec;
    37. begin
    38.   BaseDirectory := IncludeTrailingPathDelimiter('G:\SL\Supertest\');
    39.   TargetDirectory := IncludeTrailingPathDelimiter('');
    40.   Counter := 0;
    41.  
    42.   if FindFirst(BaseDirectory + '*.*', faAnyFile, SearchRec) = 0 then
    43.   begin
    44.  
    45.     repeat
    46.  
    47.       if (SearchRec.Attr and faDirectory) <> faDirectory then // faAnyFile geeft ook directories terug, die willen we niet
    48.       begin
    49.  
    50.         Inc(Counter); // hou een tellen bij per file
    51.  
    52.         if Counter mod 2500 = 1 then // per 2500
    53.         begin
    54.           // we hoeven alleen de directory aan te maken als we op een veelvoud van 1000 zitten
    55.           TargetDirectory := BaseDirectory + Format('%.3d', [Counter div 2500 + 1]);
    56.           if not ForceDirectories(TargetDirectory) then
    57.             raise Exception.CreateFmt('Error creating directory: ''%s''', [TargetDirectory]);
    58.         end;
    59.  
    60.         // de werkelijke verplaatsing
    61.         if not RenameFile(BaseDirectory + SearchRec.Name, TargetDirectory + '\' + SearchRec.Name) then
    62.           raise Exception.CreateFmt('Error moving file: ''%s''', [BaseDirectory + SearchRec.Name]);
    63.  
    64.       end;
    65.  
    66.     until FindNext(SearchRec) <> 0;
    67.  
    68.     FindClose(SearchRec);
    69.  
    70.   end;
    71. end;
    72.  
    73. end.

  11. #26
    Quote Originally Posted by WillemS View Post
    [HIGHLIGHT="Delphi"]Counter := 0;
    Het probleem ligt hier (Counter := 0).

    Ik had ook gezegd dat als je dit een tweede keer wilde laten lopen, dat je Counter op de reeds gedane aantal moet zetten.

    Je moet dus eerst kijken welke directories je allemaal hebt.
    Bijvoorbeeld 001, 002, 003.
    Dan is 003 de laatste.
    In 001 en 002 zouden dan 2500 files moeten zitten dus dat zijn er dan 5000.
    In 003 zitten bijvoorbeeld 900 files.
    Dan moet je de Counter op 5900 zetten (want dat is het aantal dat er al in staat.
    Tevens moet je de TargetDirectory op 003 zetten in het begin.

    Dan worden er als eerste 1600 files naar 003 gemoved (2500-900).
    Je Counter is na die 1600 files 7501 en dan wordt er dus weer een nieuwe directory 004 aangemaakt waar weer 2500 files in komen.

  12. #27
    mov rax,marcov; push rax marcov's Avatar
    Join Date
    Apr 2004
    Location
    Ehv, Nl
    Posts
    10,357
    Indien je counter niet met een (waarde mod 2500)=0 laat beginnen move je naar een ongewijzigde TargetDirectory '' want het counter mod 2500=1 blok wordt niet uitgevoerd om targetdirectory te vullen

    (regel 39 TargetDirectory := IncludeTrailingPathDelimiter('')

  13. #28
    De kerstvakantie is voor mij begonnen, dus verder met mijn projectje.
    Nu heb ik het schermpje wat uitgebreid met een TDirectoryEdit.
    Deze waarden worden opgeslagen in een ini bestand, zowel het schrijven als uitlezen gaat voor 50 procent goed.
    De source directory wordt netjes uitgelezen, en gebruikt.
    Target directory spartelt wat tegen, het meest haalbare wat ik gehaald heb is dat hij de mappen aanmaakt in de root, en dat was niet echt de bedoeling.
    Ik heb dan ook het volgende al gedaan.

    Code:
     Ini: TIniFile;
      B, T : String;
      Counter: integer;
      BaseDirectory, TargetDirectory: string;
      SearchRec: TSearchRec;
    begin
      Ini := TIniFile.Create('cmfsettings.ini');
      try
      b := Ini.ReadString('SDir', 'SourceD', '');
      T := Ini.ReadString('SDir', 'Target', '');
    
      BaseDirectory := IncludeTrailingPathDelimiter(b);
      TargetDirectory := IncludeTrailingPathDelimiter(T);
      Counter := 0;
    
      if FindFirst(BaseDirectory + '*.*', faAnyFile, SearchRec) = 0 then
      begin
    
        repeat
    
          if (SearchRec.Attr and faDirectory) <> faDirectory then // faAnyFile geeft ook directories terug, die willen we niet
          begin
    
            Inc(Counter); // hou een tellen bij per file
    
            if Counter mod 50 = 1 then // per 2500
            begin
              // we hoeven alleen de directory aan te maken als we op een veelvoud van 1000 zitten
              TargetDirectory := TargetDirectory + Format('%.3d', [Counter div 50 + 1]);
              if not ForceDirectories(TargetDirectory) then
                raise Exception.CreateFmt('Error creating directory: ''%s''', [TargetDirectory]);
            end;
    
            // de werkelijke verplaatsing
            if not RenameFile(BaseDirectory + SearchRec.Name, TargetDirectory + '\' + SearchRec.Name) then
              raise Exception.CreateFmt('Error moving file: ''%s''', [TargetDirectory + SearchRec.Name]);
    
          end;
    
        until FindNext(SearchRec) <> 0;
    
        FindClose(SearchRec);
    
      end;
    
      finally
        ini.Free;
      end;
    end;
    Mijn vraag is dus, wat doe ik fout hier aan?

    Alvast bedankt

  14. #29
    Even controleren wat Showmessage(TargetDirectory) geeft.

    Misschien dat T := Ini.ReadString('SDir', 'Target', ''); niet helemaal goed werkt.
    Hoe ziet je ini bestand eruit?

  15. #30
    Geweldig, het werkt, want was het probleem, bij het uitlezen van de source staat er "b := Ini.ReadString('SDir', 'SourceD', '');
    Bij de target T := Ini.ReadString('SDir', 'Target', ''); stind een fout, dit moest zijn T := Ini.ReadString('SDir', 'TargetD', ''); de D moest er nog achter, en jawel het werkt.

Page 2 of 3 FirstFirst 1 2 3 LastLast

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •