Autor Téma: Kopirovani souboruuuu  (Přečteno 2371 krát)

Offline jarex

  • Plnoletý
  • ***
  • Příspěvků: 220
  • Karma: 5
Kopirovani souboruuuu
« kdy: 23-09-2012, 19:24:21 »
Mam promennou Tsttringlist a v ni cca 40 000 polozek obsahujicich cesty k jednotlivym souborum.
V cyklu for  kopiruju soubory z jednoho disku na druhy pomoci procedury:
Kód: Delphi [Vybrat]
  1. procedure Tform2.CopyFileWithProgressBar(Source, Destination : string);
  2. var
  3.   FromF,
  4.   ToF        : file of byte;
  5.   Buffer    : array[0..4096] of char;
  6.   NumRead    : integer;
  7.   FileLength : longint;
  8. begin
  9. if not fileexists(source) then exit;
  10. if fileexists(destination) then exit;
  11.  
  12.  
  13. form2.label4.caption:='Kopírování souboru';
  14.  
  15.  form2.ProgressBar2.position:=0;
  16.   AssignFile(FromF,Source);
  17.   FileMode := fmOpenRead;
  18. reset(FromF);
  19.   AssignFile(ToF,Destination);
  20.   rewrite(ToF);
  21.   FileLength:=FileSize(FromF);
  22.   with Form2.Progressbar2 do
  23.   begin
  24.   visible:=true;
  25.     Min := 0;
  26.     Max := FileLength;
  27.     while FileLength > 0 do
  28.     begin
  29.       BlockRead(FromF,Buffer[0],SizeOf(Buffer),NumRead);
  30.       FileLength := FileLength - NumRead;
  31.       BlockWrite(ToF,Buffer[0],NumRead);
  32.       Position := Position + NumRead;
  33.       Application.ProcessMessages;
  34.     end;
  35.     CloseFile(FromF);
  36.     CloseFile(ToF);
  37.   end;
  38.   form2.ProgressBar2.Visible:=false;
  39.   form2.label3.caption:='';
  40. form2.label4.caption:='';
  41.  
  42. end;
  43.  

Je toho cca 200GB a kopiruje se to cca 7 hodin.
Pritom pomoci windowsackyho kopirovani ctrl+c ctrl+v to trva cca 1,5h.

Nevedel by nekdo, cim to je?  Zda to zpomaluje procedura CopyFileWithProgressBar?, nebo je to zapricineno necim jinym?
Dekuji.
D2007 Professional

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2668
  • Karma: 133
    • Verze Delphi: D2007, XE3, DX10
Re:Kopirovani souboruuuu
« Odpověď #1 kdy: 23-09-2012, 20:12:05 »
Nevedel by nekdo, cim to je?  Zda to zpomaluje procedura CopyFileWithProgressBar?, nebo je to zapricineno necim jinym?

Nevim. Pokud je to desktopova aplikace, tak tusim existuje API funkce CopyFile.

A pokud bych to mel implementovat nekde ve sluzbe nebo ze bych nemel co delat,
tak bych to zrychloval nasledujicimi opatrenimi:

- v hlavnim threadu bych nechal jen obsluhu progress baru
- v kazdem pripade bych to predel alespon na 2 buffery, abych mohl soucasne cist i zapisovat
- buffery bych udelal v nasobcich velikosti clusteru
- vyhodil bych archaicke pascalske I/O operace
- buffery bych obsluhoval bud pres overlapped I/O - pak rovnou pres wokenni API
- nebo bych to obsluhoval ve threadech, to bych pro I/O mohl pouzit i Delphi streamy


Offline TLama

  • Guru
  • *****
  • Příspěvků: 597
  • Karma: 31
    • Verze Delphi: 7, 2009, XE3
Re:Kopirovani souboruuuu
« Odpověď #2 kdy: 23-09-2012, 20:22:19 »
Je to tím použitím typového souboru file of Byte. Celkově by na konstrukci typu file of měli dávat speciální povolení.
Já vím, je toho plný Internet a leckterý učitel výpočetky, který prožil spokojené období děrných štítků, si ještě dnes
zajisté rád osvěží svou post-komunistickou působnost v oblasti Pascalu podobnou zhýralostí :)

Jako nejjednodušší náhradu použij např. TFileStream. Na netu bude určitě spousta příkladů...

Pak se můžeš mrknout na trochu potuněný file stream http://stackoverflow.com/q/5639531/960757
Anebo na zběsilost napsanou v C++ (která by se možná taky dala přeložit) http://ipmsg.org/tools/fastcopy.html.en
« Poslední změna: 11-12-2012, 15:55:41 od TLama »

Offline Mi.Chal.

  • Guru
  • *****
  • Příspěvků: 576
  • Karma: 25
Re:Kopirovani souboruuuu
« Odpověď #3 kdy: 23-09-2012, 21:16:33 »
to neustálé volání Application.ProcessMessages (což je samo o sobě ne moc čistá technika) tomu taky moc neprospěje

Offline RadstaR

  • Nováček
  • *
  • Příspěvků: 2
  • Karma: 0
Re:Kopirovani souboruuuu
« Odpověď #4 kdy: 23-09-2012, 21:20:49 »
Pouzivam stejnou funkci, ale bez Application.ProcessMessages a s vetsim bufferem Buffer: array [0 .. 16383] of char; a nemuzu si stezovat :)

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 2479
  • Karma: 103
    • Verze Delphi: D5,D2007, DXE, DXE2 + 2 poslední (Tokyo)
    • O Delphi v češtině
Re:Kopirovani souboruuuu
« Odpověď #5 kdy: 23-09-2012, 21:42:10 »
Taky si myslím, že hodně tomu pomůže větší buffer. Podle mne čteš 4097 a to je špatné číslo jak z hlediska nenásobku, tak velikosti. Zkus to co ti radí Radstart - [0 .. 16383] of AnsiChar
Embarcadero MVP - Czech republic

Offline jarex

  • Plnoletý
  • ***
  • Příspěvků: 220
  • Karma: 5
Re:Kopirovani souboruuuu
« Odpověď #6 kdy: 24-09-2012, 08:40:57 »
tak jsem to dal do jineho vlakna s vetsim bufferem bez Application.ProcessMessages a vypada to o dost lepsi.
D2007 Professional

Offline < z >

  • Administrátoři
  • Guru
  • *****
  • Příspěvků: 1136
  • Karma: 42
    • Verze Delphi: 7, 2010
Re:Kopirovani souboruuuu
« Odpověď #7 kdy: 24-09-2012, 09:19:30 »
no podivej se do Total Commanderu, je tam nekolik moznosti kopirovani a nastaveni bufferu,

mas moznost vyuzit klasicke Windows API ke kopirovani, pripadne i Windows dialog s tim progressbarem,
tim nic nezkazis

kopirovani bez WinAPI je dobry orisek pro dosazeni maximalni rychlosti,
maly buffer je dobry pro male soubory, pokud kopirujes velke soubory,
tak nejaky 16kB buffer porad nebude dost ... vyuzivam 10MB buffer a to pak jinak svisti ...
asi bych zvazil pouzit to FastCopy

a ProcessMessages je nejvetsi brzda, o tom zadna
(na tohle opravdu jen vlakno, pri nejhorsim to pouzit jen kazdych nekolik sekund na aktualizaci)

Offline JaroB

  • Guru
  • *****
  • Příspěvků: 984
  • Karma: 27
    • Verze Delphi: XE8, Seattle
Re:Kopirovani souboruuuu
« Odpověď #8 kdy: 24-09-2012, 10:18:01 »
Ve své podstatě může být buffer stejně velký jako je kopírovaný soubor (ale tím nemyslím zrovna CD na 730 MB, ale rozumné násobky 1024 B). Pevný buffer se používal, protože byla velká režie na realokaci, bylo to laciné a šlo to okopírovat rovnou z příkladu z helpu.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2668
  • Karma: 133
    • Verze Delphi: D2007, XE3, DX10
Re:Kopirovani souboruuuu
« Odpověď #9 kdy: 24-09-2012, 10:33:11 »
Ve své podstatě může být buffer stejně velký jako je kopírovaný soubor (ale tím nemyslím zrovna CD na 730 MB, ale rozumné násobky 1024 B).
Pokud se jedna operace s diskem, tak by buffer mel mit nasobky nejmensi alokovatelne jednotky na disku a to je cluster.

Pevný buffer se používal, protože byla velká režie na realokaci, bylo to laciné a šlo to okopírovat rovnou z příkladu z helpu.
Tomu nerozumim: jak souvisi buffer pro I/O operace s realokaci? Proste sis rekl memory manageru o kus souvisle pameti  a s jejim obsahem sis delal, cos chtel...

Offline JaroB

  • Guru
  • *****
  • Příspěvků: 984
  • Karma: 27
    • Verze Delphi: XE8, Seattle
Re:Kopirovani souboruuuu
« Odpověď #10 kdy: 24-09-2012, 11:17:57 »
Ale pokud byl buffer statický, tak veškerá režie (kromě Flush) odpadla :)

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2668
  • Karma: 133
    • Verze Delphi: D2007, XE3, DX10
Re:Kopirovani souboruuuu
« Odpověď #11 kdy: 24-09-2012, 11:26:58 »
Ale pokud byl buffer statický, tak veškerá režie (kromě Flush) odpadla :)
Aha, takze tys mel na mysli alokaci, ne realokaci... Ale prece neni problem si u aplikaci se stackem 1 MB by default definovat lokalni automatickou promennou na stacku treba o velikosti 64 kB, zejmena pro long lasting operace, kdyz zbytek aplikace nedela soucasne skoro nic jineho.

Offline TLama

  • Guru
  • *****
  • Příspěvků: 597
  • Karma: 31
    • Verze Delphi: 7, 2009, XE3
Re:Kopirovani souboruuuu
« Odpověď #12 kdy: 25-09-2012, 07:50:41 »
Hele, jestli se na tohle někdo ptal na SO, pak bych k tomu (a to i tak) doporučoval použít
samostatné vlákno a posílat z něj zprávy s aktuálníma hodnotama progresu do okna GUI
threadu. Tím by se dalo snadno zbavit toho Application.ProcessMessages.

Jinak má ten tazatel, ať už to byl kdokoli ode mě malé bezvýznamné +1 :)
http://stackoverflow.com/questions/12576325/treadonlycachedfilestream-error-on-files-greater-than-2-gb
« Poslední změna: 11-12-2012, 15:55:13 od TLama »