Autor Beitrag
IhopeonlyReader
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: So 08.09.13 14:21 
Guten Tag,
mir geht es nur um die Absicherung.

Ich verwende TSearchRec um alle Dateien in einem Ordner durchzugehen. Wenn ich eine Datei gefunden habe, bennene ich sie um.
Ist es ein Problem, dass die Datei umbenannt wird, könnte sie dadurch ein 2tes mal gefunden werden?

aktuell wird jede Datei nur 1x gefunden, aber ich möchte mir damit keine Dauerschleife einbauen..

oder muss ich eine TStringlist verwenden, alle Dateinamen dort reinschreiben und am ende alle umbenennen?

_________________
Sucht "neueres" Delphi :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 08.09.13 16:40 
user profile iconIhopeonlyReader hat folgendes geschrieben Zum zitierten Posting springen:
oder muss ich eine TStringlist verwenden, alle Dateinamen dort reinschreiben und am ende alle umbenennen?
Ja. Es wird immer die nächste zu passende Datei gesucht, und das kann auch eine der bereits umbenannten sein.

Dass du selbst die umbenannt hast, kann Windows ja an der Stelle nicht wissen. Und wenn ein anderes Programm in dem Moment eine Datei dort ablegen würde, würdest du sie ja finden wollen...

Für diesen Beitrag haben gedankt: IhopeonlyReader
IhopeonlyReader Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: So 08.09.13 17:32 
das stimmt, ich wollte mich nur absichern. So werde ich das ganze wohl eben umbauen müssen.. erst Dateien finden dann umbennen :)

Für alle die es intressiert, so sieht die "neue" procedure aus

ausblenden Delphi-Quelltext
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:
procedure FindInDir( aDir: String; PreName: String; SavedPaths: TStrings );
var SR: TSearchRec;
begin
aDir := IncludeTrailingPathDelimiter( aDir );
if length(PreName)>0 then
  PreName := IncludeTrailingPathDelimiter( PreName );
if FindFirst( aDir + '*.*', faAnyFile, SR ) = 0 then
  try
    repeat
      if (SR.Attr and faDirectory) = faDirectory then
        begin
        if (SR.Name <> '.'and (SR.Name <> '..'then
          begin
          FindInDir( aDir + SR.Name, PreName + SR.Name, SavedPaths );         // Ordner
          end;
        end
        else // if (SR.Attr and faDirectory) <> faDirectory then
          begin
          SavedPaths.Add( PreName + SR.Name );  //Datei
          end;
      until FindNext(SR) <> 0;
  finally
    FindClose(SR);
  end;
end;

Bei einem Ordner wird die Funktion selbst nochmal aufgerufen.
Da ich auf "unnötige" Speichernutzung nicht so stehe, schreibe ich nicht den kompletten Pfad in die Stringlist. das wäre allerdings ebenso möglich:
ausblenden Delphi-Quelltext
1:
FindInDir( PfadName, Pfadname, DieStringList );					

da das wie gesagt speicher ohne ende bei vielen Dateien schlucken würde ( length(Pfadname)*sizeof(char)*AnzahlErgebnisse in Byte ) rufe ich die procedure lieber so auf:
ausblenden Delphi-Quelltext
1:
FindInDir( PfadName, '', DieStringList );					

Wenn man dann mit den Pfaden arbeiten will macht man einfach:
ausblenden Delphi-Quelltext
1:
2:
For C:=0 to dieStringlist.count-1 do
  ArbeiteMitPfad( Pfadname + DieStringList[C] );


seht ihr direkt fehler, oder ist alles top?
wie findet ihr die Idee mit dem prename?

_________________
Sucht "neueres" Delphi :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 08.09.13 19:28 
So viel Speicher sparst du dadurch zwar nicht, aber schaden tut es ja auch nicht. (Auch wenn es das ganze logischerweise etwas langsamer macht, da immer der Pfad beim Abarbeiten davorgesetzt werden muss.)

Sieht so gut aus, ja. Nebenbei, nur zum Vergleich, würde das gleiche in Delphi XE4 komplett so aussehen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
uses
  IOUtils;

var
  CurrentFile: string;
begin
  for CurrentFile in TDirectory.GetFiles(TargetPath, '*.*', TSearchOption.soAllDirectories) do
    ArbeiteMitPfad(CurrentFile);
IhopeonlyReader Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: So 08.09.13 19:41 
ja, ich habe nuneinmal Delphi 7 und wenn man soetwas nicht kennt, stört es einen auch nicht :)
bei mir wird wenigstens der Sinn dahinter bzw. wie es funktioniert verstanden ;)



user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
So viel Speicher sparst du dadurch zwar nicht, aber schaden tut es ja auch nicht. (Auch wenn es das ganze logischerweise etwas langsamer macht, da immer der Pfad beim Abarbeiten davorgesetzt werden muss.)

Langsamer denke ich nicht, ob der Dateiname beim "finden" davorgesetzt wird oder beim namensersetzten.

und man spart finde ich schon viel. Wenn ich meine Festplatte (2te) durchgehe die mit D:\ beginnt, wären das 3 Byte pro Datei.
das sind bei mir ca 0,3 MB ( 313 KB );

und nochmal zur Schnelligkeit, ich gehe sogar davon aus, dass meine Variante schneller ist, da der String beim direktreinschreibenr 1x gelesen und 1x gesetzt wird. beim späteren zusammensetzten wird es halt nur zusammengesetzt...
Ebenso muss bei mir der Zeiger innerhalb der Stringlist weniger springen..

Natürlich sind das alles keine größen Zeiten.. ich benötige mit meinem "verschlüsselungsprogramm" für 8 Gb ca 10 sek. Hier wird ein ganzer ordner "gesucht", jede Datei dann eingelesen und dann verschlüsselt und zuletzt wieder überschrieben.
da stören wenige MS auch nicht mehr :D ;)

_________________
Sucht "neueres" Delphi :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 08.09.13 22:18 
user profile iconIhopeonlyReader hat folgendes geschrieben Zum zitierten Posting springen:
Natürlich sind das alles keine größen Zeiten.. ich benötige mit meinem "verschlüsselungsprogramm" für 8 Gb ca 10 sek. Hier wird ein ganzer ordner "gesucht", jede Datei dann eingelesen und dann verschlüsselt und zuletzt wieder überschrieben.
Da selbst die schnellste Consumer SSD von der Geschwindigkeit her die 8 GiB (oder meinst du wirklich Gb, also Gigabit?) in der Zeit nicht einmal lesen kann und der Cache dafür zu klein sein dürfte, muss da wohl ein Fehler drin sein. ;-)

Und wenn du dann noch mit einem TFileStream byteweise darin arbeitest und immer wieder byteweise zurück springst wie in dem anderen Thread zu sehen war, ist die Geschwindigkeit noch viel geringer.
IhopeonlyReader Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: So 08.09.13 22:46 
170 gb also Gigabyte! in 36 sek war mein letzter Test
Also verschlüsseln dauert so lange. Entschlüsseln ist noch schneller..
Mit umbenennen, filename in Datei und Byte für Byte mit einer Maske xor.. Wobei auch die Maske in der Zeit erstellt wird

Nachtrag; Dateien finden ist in der Zeit auch drin ;)

_________________
Sucht "neueres" Delphi :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 08.09.13 23:02 
user profile iconIhopeonlyReader hat folgendes geschrieben Zum zitierten Posting springen:
170 gb also Gigabyte! in 36 sek war mein letzter Test
Also verschlüsseln dauert so lange. Entschlüsseln ist noch schneller..
Mit umbenennen, filename in Datei und Byte für Byte mit einer Maske xor..
Überleg doch mal bitte selbst. Das entspräche einer Übertragungsrate von über 4 GiB pro Sekunde...
Wie soll das gehen? Das ist weit mehr als dein Festplattencontroller schafft, egal ob da eine SSD oder eine Festplatte dranhängt. Das ist absolut unmöglich außer mit Hardware im wahrscheinlich fünfstelligen Eurobereich.

Gibt es das Tool irgendwo zum testen? ;-)
IhopeonlyReader Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: So 08.09.13 23:11 
Hmmm.. Es war alles verschlüsselt und so wie es soll.. Wenn es nicht möglich sein soll, sehe ich das mal als Kompliment ;)
Meine festplatte ist eine 1 TB SATA2 7200rpm
Ums vorstellen kümmer ich mich morgen nach ein paar Tests :)
Und eig wollte ich das ganze noch verschnellern indem ich "größere" Teile einlade in einen MemoryStream und dann xor, aber scheinbar ist reiner filestream schnell genug :D

_________________
Sucht "neueres" Delphi :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 09.09.13 07:20 
user profile iconIhopeonlyReader hat folgendes geschrieben Zum zitierten Posting springen:
Und eig wollte ich das ganze noch verschnellern indem ich "größere" Teile einlade in einen MemoryStream und dann xor :D
Am schnellsten wäre eine MMF.
Gerd Kayser
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 632
Erhaltene Danke: 121

Win 7 32-bit
Delphi 2006/XE
BeitragVerfasst: Mo 09.09.13 08:30 
user profile iconIhopeonlyReader hat folgendes geschrieben Zum zitierten Posting springen:
Und eig wollte ich das ganze noch verschnellern indem ich "größere" Teile einlade in einen MemoryStream und dann xor, aber scheinbar ist reiner filestream schnell genug :D

1. Bei einem MemoryStream bekommst Du Probleme bei sehr großen Dateien. Die könnten evtl. nicht ins RAM passen.
2. Bei einem FileStream kannst Du die Geschwindigkeit erhöhen, wenn Du entsprechend große Buffer verwendest.
Vor einigen Jahren lief mal eine Diskussion in der Newsgroup de.comp.lang.delphi.misc zum Thema "Laufzeit-Optimierung". Da ging es um die Frage, wie man bei einer 110 MB großen Textdatei am schnellsten alle Leerzeichen entfernen kann. Hier mal die gemessenen Zeiten:

Zitat:
Bei einer Textdatei mit 111.250.273 Bytes ergaben sich folgende
Laufzeiten (BDS 2006, Intel-Quadcore-CPU mit 3 GHz):

1. BlockRead (Buffergröße = 1) zum Lesen. Bytes mit BlockWrite
(Buffer = 1) schreiben, sofern kein Leerzeichen.
Dauer: 16 Minuten und 27 Sekunden

2. Mit FileStream einlesen und in einen Ausgabe-FileStream
byteweise kopieren, sofern kein Leerzeichen.
Dauer: 19 Minuten und 21 Sekunden

3. Mit BlockRead byteweise einlesen und in einen MemoryStream
byteweise kopieren, sofern kein Leerzeichen. Dann mit
SaveToFile abspeichern.
Dauer: 8 Minuten und 38 Sekunden

4. Der 4. Versuch war zwar der, der die meisten Resourcen (RAM)
benötigt, aber auch der schnellste.
Einlesen in einem MemoryStream, byteweises kopieren (ohne Leer-
zeichen) in einen weiteren MemoryStream, der dann mit
SaveToFile abgespeichert wurde.
Dauer: 5 (in Worten: fünf) Sekunden


Dann das Ganze optimiert mit Buffern:

Zitat:
InBuf, OutBuf : array [0..1024] of Byte; --> 1158 Millisekunden.
InBuf, OutBuf : array [0..4095] of Byte; --> 573 Millisekunden.
InBuf, OutBuf : array [0..65535] of Byte; --> 281 Millisekunden.
InBuf, OutBuf : array [0..262143] of Byte; --> 266 Millisekunden.


Quelle: groups.google.com/fo...ST3tVkg/H3p8SwpuLzAJ
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 09.09.13 09:56 
Eine MMF sollte dennoch noch schneller sein, da Windows die Synchronisation mit dem realen Dateiinhalt übernimmt und optimieren kann. Zudem ist es sehr einfach, da man einfach Pointer auf den Datenbereich nutzen kann ohne sich darum zu kümmern, dass die Daten aus der Datei auch dort landen.
Eine 350 MiB Datei byteweise eingelesen und in einem Baum angezeigt habe ich so auch in deutlich unter 10 Sekunden eingelesen, nämlich hiermit:
www.entwickler-ecke....5&view=df#607865

Da hier die Datenmenge gleich bleibt, kann direkt inplace geändert werden, das sollte daher relativ gut an die Festplattengeschwindigkeit herankommen.
Gerd Kayser
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 632
Erhaltene Danke: 121

Win 7 32-bit
Delphi 2006/XE
BeitragVerfasst: Mo 09.09.13 11:01 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
das sollte daher relativ gut an die Festplattengeschwindigkeit herankommen.

Die Geschwindigkeit wird aber auch durch andere Faktoren bestimmt, z. B.:
- im Hintergrund laufender Virenscanner
- Fragmentierungsgrad der Partition bzw. einzelner Dateien
- sonstige Festplattenzugriffe
Wenn ich mir hier mit ACDSEE einen Bildkatalog meiner sehr umfangreichen Bildersammlung neu erstelle, sehe ich manchmal, dass eine der Datenbanktabellen an die 200.000 Fragmente hat. Alleine das Kopieren dieser Datei geht dann schon in den Minutenbereich.
IhopeonlyReader Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: Mo 09.09.13 14:12 
oO.. ich wunder mich über solche Zeiten :O
Entweder funktioniert bei mir etwas falsch oder ich habe "ausversehen" eine superschnelle-Festplatte :D
die tests mit 8 GB liefen in einer nicht messbaren Zeit (gegen 0 millisek)

und ihr redet hier von 110MB-Textdateien für die zwischen 5 sek und 16,5 Minuten gebraucht wird....
ich hätte das so gemacht
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
var WritePos, C: Int64;
FS: TFileStream;
aByte: Byte;
begin
WritePos := 0;
//Filestream erstellen +ggf. initialisieren
try
For C:=1 to FS.Size do
  begin
  FS.Read( aByte, 1 ); //einlesen
  if (aByte <> 1then //wenn es kein Leerzeichen ist
   begin
   FS.Seek( WritePos, soFromBeginning ); //gehe auf schreibposition
   FS.WriteBuffer( aByte, 1 ); //überschreibe das Byte (das "nicht Leerzeichen")
   inc( WritePos );  //erhöhe schreibposition
   FS.Seek( C, soFromBeginning );  //gehe zurück zur leseposition
   end;
  end;
//nächste Zeile, Korrektur dank jaenicke ;) 
 FS.Size := WritePos; // Datei wird so groß, wie viele Bytes geschrieben wurden
 finally
 FS.Free;
 end;  
end;


PS: ich werde noch einige Tests mit meinem "Xor"-Programm durchführen und dann euch freigeben ;)..
Letzte Tests: 8 GB in >1ms
170 GB in 36,4 sek (verschlüsseln)
170 GB in 13,4 sek (entschlüsseln)

ich werde jetzt noch FileStream gegen FastFileStream eintauschen und MemoryStream ausprobieren
Zitat:
von user profile iconGerd Kayser
1. Bei einem MemoryStream bekommst Du Probleme bei sehr großen Dateien. Die könnten evtl. nicht ins RAM passen.

ich hatte daran gedacht eine konstante buffersize anzugeben z.B. 1 GB. wenn die Datei < 1 GB ist dann komplett in memorystream einladen. Sonst ersten GB, dann zweite..

_________________
Sucht "neueres" Delphi :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!


Zuletzt bearbeitet von IhopeonlyReader am Mo 09.09.13 14:43, insgesamt 1-mal bearbeitet
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 09.09.13 14:25 
user profile iconIhopeonlyReader hat folgendes geschrieben Zum zitierten Posting springen:
ich hätte das so gemacht
Int64 bei einer Schleifenvariablen? Zumindest bei Delphi XE4 geht das nicht.

Am Ende die Größe auf alte Größe minus die geschriebenen Bytes zu setzen ist mutig. Denn wenn du z.B. 100 Byte in der Datei hast und davon 5 gelöscht werden, hast du 100 Byte vorher gehabt, 95 geschrieben...
...und die neue Größe ist 100 - 95, also 5!

Dein Code braucht hier 5 Sekunden pro MiB und das ist auch ein Wert, den ich bei deiner unoptimierten byteweisen Herangehensweise mit den ganzen Seeks erwartet hätte. Bei deinen 170 GiB wären das runde 10 Tage Laufzeit.
Mehr dazu kann ich erst heute Abend schreiben...
IhopeonlyReader Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: Mo 09.09.13 14:50 
wurde oben im quelltext geändert :)
und Int64, ok dann würde ich Cardinal verwenden und rundrum eine repeat schleife bauen, damit falls die Datei>MaxCardinal ist es trotzdem klappt.

(Alle Zeiten für Einen 170 GigaByte großen Ordner)
Und 10 Tage für 170 GB :D in Delphi waren es jetzt 1:12.725 (1 min 12 sek 725 millisek ), zum decrypten 47 sek und 499 millisek
ohne Compiler waren es maximal 54 sek und 361 millisek (encrypten) zum decrypten 43 sek und 302 millisek.

bester Test:
Encrypt: 30.5 sek
Decrypt: 17.4 sek

_________________
Sucht "neueres" Delphi :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 09.09.13 15:29 
Das ist trotzdem absolut unmöglich. Und wie schon geschrieben, dein Code oben dauert jedenfalls deutlich länger.

Wenn du ein komplettes Projekt zum Testen hast, lässt sich sicher auch sagen was da passiert.
IhopeonlyReader Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: Mo 09.09.13 15:47 
bin gerade dabei fehler zu finden, scheinbar werden nur bestimmte Bytes ver/ent-schlüsselt und nicht die ganze Datei.
nach einer korrektur treffen eure Zeiten zu.
600 KB in 6 sek.

deswegen bin ich vor der Öffentlichung noch dabei das zu verschnellern

_________________
Sucht "neueres" Delphi :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!