Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Datei mit Steuerzeichen in StringList laden? (https://www.delphipraxis.net/193195-datei-mit-steuerzeichen-stringlist-laden.html)

SneakyBagels 4. Jul 2017 08:16

Datei mit Steuerzeichen in StringList laden?
 
Ist es möglich mit einer normalen StringList (oder etwas anderem was bei Delphi dabei ist) eine Datei die die, die man in folgendem Verzeichnis findet in einen String zu laden?
Ziel ist es: ich möchte einen SubString in der Datei finden und dafür keine extra 3rd Party Unit verwenden.

=> C:\Users\<name>\AppData\Roaming\Microsoft\Windows\ Recent\CustomDestinations

TiGü 4. Jul 2017 08:34

AW: Datei mit Steuerzeichen in StringList laden?
 
Es ist alles möglich.
Delphi-Quellcode:
program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  System.Classes;

var
  Stream: TStringStream;
  filename: string;
begin
  try
    filename := 'C:\Users\Horst\AppData\Roaming\Microsoft\Windows\Recent\CustomDestinations\e0e944739d076ab.customDestinations-ms';

    Stream := TStringStream.Create;
    Stream.LoadFromFile(filename);
    Writeln(Stream.DataString);
    Stream.Free;
    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

SneakyBagels 4. Jul 2017 08:40

AW: Datei mit Steuerzeichen in StringList laden?
 
An Streams habe ich noch nicht gedacht.
Leider ist bei mir DataString immer leer. Selbst wenn die Datei offensichtlich eine Größe > 0Byte hat.

Uwe Raabe 4. Jul 2017 09:13

AW: Datei mit Steuerzeichen in StringList laden?
 
Zitat:

Zitat von SneakyBagels (Beitrag 1375901)
Ist es möglich mit einer normalen StringList (oder etwas anderem was bei Delphi dabei ist) eine Datei die die, die man in folgendem Verzeichnis findet in einen String zu laden?

Ist es: TFile.ReadAllText

TiGü 4. Jul 2017 09:25

AW: Datei mit Steuerzeichen in StringList laden?
 
Zitat:

Zitat von SneakyBagels (Beitrag 1375907)
An Streams habe ich noch nicht gedacht.
Leider ist bei mir DataString immer leer. Selbst wenn die Datei offensichtlich eine Größe > 0Byte hat.

Wie groß ist denn Stream.Size nach dem laden?

SneakyBagels 4. Jul 2017 09:32

AW: Datei mit Steuerzeichen in StringList laden?
 
Zitat:

TFile.ReadAllText
Auch TFile.ReadAllText hat Probleme mit den .customDestinations-ms-Dateien und zeigt keinen Inhalt an (showmessage)

Zitat:

Wie groß ist denn Stream.Size nach dem laden?
Das weiß ich nicht ich habe wieder alles gelöscht was mit Streams zu tun hatte. Es war vermutlich aber 0.

Zum Vergleich: diese Unit schafft es die Dateien zu lesen
http://www.delphipraxis.net/151898-s...ei-reader.html

TiGü 4. Jul 2017 09:49

AW: Datei mit Steuerzeichen in StringList laden?
 
Zitat:

Zitat von SneakyBagels (Beitrag 1375917)
Das weiß ich nicht ich habe wieder alles gelöscht was mit Streams zu tun hatte. Es war vermutlich aber 0.

Das Öffnen der IDE dauert in der Regel länger als das einkopieren meines Quelltextes, die Anpassung des Pfades und das Drücken von F9.
So debugge er es hin!

SneakyBagels 4. Jul 2017 10:01

AW: Datei mit Steuerzeichen in StringList laden?
 
Size ist nicht 0.
Size entspricht der Dateigröße in Bytes.

Uwe Raabe 4. Jul 2017 10:01

AW: Datei mit Steuerzeichen in StringList laden?
 
Zitat:

Zitat von SneakyBagels (Beitrag 1375917)
Zitat:

TFile.ReadAllText
Auch TFile.ReadAllText hat Probleme mit den .customDestinations-ms-Dateien und zeigt keinen Inhalt an (showmessage)

Das liegt dann wohl daran, daß das eben keine reinen Textdateien sind und das erste 0-Byte den String terminiert. In dem Fall würde ich dann TFile.ReadAllBytes empfehlen.

Der schöne Günther 4. Jul 2017 10:03

AW: Datei mit Steuerzeichen in StringList laden?
 
Haben wir denn eine konkrete Beispiel-Datei? Wenn ich mitten in eine "Text"-Datei ein Nullbyte reinpacke hat ReadAllText damit kein Problem:

Delphi-Quellcode:
uses
   System.SysUtils,
   System.Classes,
   System.IoUtils;
const
   filePath = 'x:\someFile.dat';
   DLE = 16;
   NULL = 0;
var
   bytes: TBytes;
   stream: TStream;
   fileContent: String;
begin
   // 1) Datei schreiben
   TFile.WriteAllText(filePath, 'Vor Steuerzeichen');
   bytes := [DLE, NULL];
   stream := TFile.OpenWrite(filePath);
   try
        stream.Seek(0, TSeekOrigin.soEnd);
      stream.Write(bytes, 2);
   finally
      stream.Destroy();
   end;
   TFile.AppendAllText(filePath, 'Nach Steuerzeichen');

   // 2) Datei lesen (einfach)
   fileContent := TFile.ReadAllText(filePath);
   WriteLn( fileContent.QuotedString());

   ReadLn;
end.

SneakyBagels 4. Jul 2017 10:07

AW: Datei mit Steuerzeichen in StringList laden?
 
Zitat:

Haben wir denn eine konkrete Beispiel-Datei?
Ja. Siehe Beitrag #1. Alle Dateien in C:\Users\<name>\AppData\Roaming\Microsoft\Windows\ Recent\CustomDestinations

TiGü 4. Jul 2017 10:11

AW: Datei mit Steuerzeichen in StringList laden?
 
Zitat:

Zitat von SneakyBagels (Beitrag 1375925)
Zitat:

Haben wir denn eine konkrete Beispiel-Datei?
Ja. Siehe Beitrag #1. Alle Dateien in C:\Users\<name>\AppData\Roaming\Microsoft\Windows\ Recent\CustomDestinations

Er meinte eher sowas wie:
"SneakyBagels, lade doch bitte eine Beispieldatei von DIR hoch, weil bei mir in diesem Ordner 39 Dateien zu finden sind, die zwischen 12 und 25.262 KB groß sind."

Der schöne Günther 4. Jul 2017 10:14

AW: Datei mit Steuerzeichen in StringList laden?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Vor allem sind das, zumindest bei mir, reine Binärdateien. Irgendwo scheint einmal Text drin zu sein, aber so etwas verwaltet man nicht als String.

TiGü 4. Jul 2017 10:18

AW: Datei mit Steuerzeichen in StringList laden?
 
Wahrscheinlich wäre es sinnvoller zu fragen, was Sneaky eigentlich genau erreichen möchte?

Es gibt möglicherweise eine Windowsfunktion für die Information, die er erfahren möchte.

SneakyBagels 4. Jul 2017 10:24

AW: Datei mit Steuerzeichen in StringList laden?
 
Zitat:

Zitat von TiGü (Beitrag 1375933)
Wahrscheinlich wäre es sinnvoller zu fragen, was Sneaky eigentlich genau erreichen möchte?

Zitat:

Ziel ist es: ich möchte einen SubString in der Datei finden und dafür keine extra 3rd Party Unit verwenden.
:P

Es hat nun funktioniert.

Delphi-Quellcode:
var
 aFile, sSubStr: String;
 AnsiStr: AnsiString;
 ByteArray: TArray<Byte>;
begin
 sSubStr := 'DasHierMussGefundenWerden';

 aFile := 'C:\Users\<name>\AppData\Roaming\Microsoft\Windows\Recent\CustomDestinations\27932e73jddafda77b.customDestinations-ms';

 ByteArray := TFile.ReadAllBytes(aFile);
 try
  if Length(ByteArray) > 0 then
   begin
    SetString(AnsiStr, PAnsiChar(@ByteArray[0]), Length(ByteArray));

    if Pos(sSubStr, AnsiUpperCase(AnsiStr)) - 1 > 0 then
     // tue etwas, wenn sSubStr in aFile gefunden wurde
   end;
 finally
  SetLength(ByteArray, 0);
 end;
Eins möchte ich betonen: Herr Jaenikes Units ist wirklich super!
Aber da ich aktuell mein Projekt aufräume und ich versuche einen gewissen Standard einzuhalten, versuche ich Units, die ich nur ein-, höchstens zwei- oder dreimal verwende durch andere Möglichkeiten zu ersetzen.

Beispiel. Was vorher so aussah...
Delphi-Quellcode:
var
 sCurrLine, sRes: string;
 FileReaderEx: TFastFileReader;
begin
 sRes := '';

 if FileExists(aFile) then
  begin
   FileReaderEx := TFastFileReader.Create(aFile);

   try
    while FileReaderEx.Position < FileReaderEx.Size do
     begin
      FileReaderEx.ReadLn(sCurrLine);

      sRes := sRes + sLineBreak + sCurrLine;
     end;
   finally
    FileReaderEx.Free;
   end;
  end;

 {$WARNINGS OFF}
 Result := Trim(UTF8toString(sRes));
 {$WARNINGS ON}
end;
Sieht nun so aus
Delphi-Quellcode:
begin
 if FileExists(aFile) then
  Result := TFile.ReadAllText(aFile, TEncoding.UTF8);

 Result := Trim(Result);
end;

Uwe Raabe 4. Jul 2017 10:50

AW: Datei mit Steuerzeichen in StringList laden?
 
Zitat:

Zitat von SneakyBagels (Beitrag 1375935)

Es hat nun funktioniert.

Delphi-Quellcode:
var
 aFile, sSubStr: String;
 AnsiStr: AnsiString;
 ByteArray: TArray<Byte>;
begin
 sSubStr := 'DasHierMussGefundenWerden';

 aFile := 'C:\Users\<name>\AppData\Roaming\Microsoft\Windows\Recent\CustomDestinations\27932e73jddafda77b.customDestinations-ms';

 ByteArray := TFile.ReadAllBytes(aFile);
 try
  if Length(ByteArray) > 0 then
   begin
    SetString(AnsiStr, PAnsiChar(@ByteArray[0]), Length(ByteArray));

    if Pos(sSubStr, AnsiUpperCase(AnsiStr)) - 1 > 0 then
     // tue etwas, wenn sSubStr in aFile gefunden wurde
   end;
 finally
  SetLength(ByteArray, 0);
 end;

Das könnte man eventuell noch etwas optimieren:

Delphi-Quellcode:
uses
  System.IOUtils, System.StrUtils;
...
var
  aFile, sSubStr: String;
  ByteArray: TBytes;
  newPos: PAnsiChar;
begin
  sSubStr := 'DasHierMussGefundenWerden';

  aFile := 'C:\Users\<name>\AppData\Roaming\Microsoft\Windows\Recent\CustomDestinations\27932e73jddafda77b.customDestinations-ms';

  ByteArray := TFile.ReadAllBytes(aFile);
  if Length(ByteArray) > 0 then
  begin
    newPos := SearchBuf(PAnsiChar(@ByteArray[0]), Length(ByteArray), 0, 0, AnsiString(sSubStr), [soDown]);
    if newPos <> nil then begin
      // tue etwas, wenn sSubStr in aFile gefunden wurde
    end;
  end;
end;

SneakyBagels 4. Jul 2017 10:54

AW: Datei mit Steuerzeichen in StringList laden?
 
Ich nehme an
Zitat:

[dcc32 Warnung] W1000 Symbol 'SearchBuf' ist veraltet: 'Moved to the AnsiStrings unit'
kann ich einfach ignorieren?

Und dann noch die Frage:
gibt es irgendeinen Unterschied zwischen
Delphi-Quellcode:
ByteArray: TBytes;
und
Delphi-Quellcode:
ByteArray: TArray<Byte>;
?
Weil laut Deklaration in System sehe ich keinen.

Ich kenne mich mit Pointern kein bisschen aus. Ist es auch möglich nun die Position von newPos herauszufinden? InToStr() funktioniert hier leider nicht.

Uwe Raabe 4. Jul 2017 11:35

AW: Datei mit Steuerzeichen in StringList laden?
 
Zitat:

Zitat von SneakyBagels (Beitrag 1375937)
Ich nehme an
Zitat:

[dcc32 Warnung] W1000 Symbol 'SearchBuf' ist veraltet: 'Moved to the AnsiStrings unit'
kann ich einfach ignorieren?

Kannst du ignorieren, denn wenn du AnsiStrings und StrUtils einbindest, kommt der Fehler "Doppeldeutiger überladener Aufruf von 'SearchBuf'".

Zitat:

Zitat von SneakyBagels (Beitrag 1375937)
Und dann noch die Frage:
gibt es irgendeinen Unterschied zwischen
Delphi-Quellcode:
ByteArray: TBytes;
und
Delphi-Quellcode:
ByteArray: TArray<Byte>;
?
Weil laut Deklaration in System sehe ich keinen.

Nein, ist von der Deklaration her kein Unterschied. Allerdings kann man ein
Delphi-Quellcode:
TArray<Byte>
nicht immer dort einsetzen, wo ein
Delphi-Quellcode:
TBytes
erwartet wird. Deswegen nimmt man besser gleich
Delphi-Quellcode:
TBytes
.

Zitat:

Zitat von SneakyBagels (Beitrag 1375937)
Ich kenne mich mit Pointern kein bisschen aus. Ist es auch möglich nun die Position von newPos herauszufinden? InToStr() funktioniert hier leider nicht.

Klar geht das:
Delphi-Quellcode:
I := newPos - @ByteArray[0];
(es lebe die Pointer-Arithmetik!)

Je nachdem, was du genau machen willst, ist das aber vielleicht gar nicht nötig.

SneakyBagels 4. Jul 2017 11:46

AW: Datei mit Steuerzeichen in StringList laden?
 
Ich habe gerade mal messen lassen. Selbe Funktion mit Pos() statt SearchBuf() ist um 50% schneller. Wie kann das sein? Ich dachte Pointer sind das Ultimative Etwas?

TiGü 4. Jul 2017 12:28

AW: Datei mit Steuerzeichen in StringList laden?
 
Zitat:

Zitat von SneakyBagels (Beitrag 1375935)
Zitat:

Zitat von TiGü (Beitrag 1375933)
Wahrscheinlich wäre es sinnvoller zu fragen, was Sneaky eigentlich genau erreichen möchte?

Zitat:

Ziel ist es: ich möchte einen SubString in der Datei finden und dafür keine extra 3rd Party Unit verwenden.
:P

Danke danke, mein Lese- und Textverständnis ist im Gegensatz zu anderen ganz ausgezeichnet.
Von daher wäre es vielleicht doch ganz hilfreich zu wissen, WAS genau du in der Datei suchst.
Höchstwahrscheinlich kannst du das nämlich viel eleganter mit der Shell-API von Windows abfrühstücken.

http://blogs.microsoft.co.il/sasha/2...-destinations/
https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx
https://tzworks.net/prototype_page.php?proto_id=20
http://www.mycsharp.de/wbb2/thread.php?threadid=105016

SneakyBagels 4. Jul 2017 12:30

AW: Datei mit Steuerzeichen in StringList laden?
 
Also ich weiß nicht was ich antworten soll, denn das habe ich doch schon zweimal geschrieben was gesucht wird :roll:
Das Problem ist ja aber schon gelößt.

Uwe Raabe 4. Jul 2017 12:42

AW: Datei mit Steuerzeichen in StringList laden?
 
Zitat:

Zitat von SneakyBagels (Beitrag 1375942)
Ich habe gerade mal messen lassen. Selbe Funktion mit Pos() statt SearchBuf() ist um 50% schneller. Wie kann das sein? Ich dachte Pointer sind das Ultimative Etwas?

Die Implementation von Pos ist halt intern auch pointer-basiert (und da sieht man, daß die RTL von Haus aus schon recht performant ist). Allerdings wird durch das AnsiUpperCase ein zusätzlicher Buffer mit den in Großbuchstaben umgewandelten Zeichen angelegt (was bei Binärdaten etwas fragwürdig ist), während SearchBuf direkt auf dem eingelesenen Buffer arbeitet. Solange die Datei klein ist, sollte das aber nicht wirklich relevant sein. Dann kannst du auch die schnellere Variante nehmen. Falls du auf das Uppercase ganz verzichten könntest, wäre das natürlich noch besser.

TiGü 4. Jul 2017 12:43

AW: Datei mit Steuerzeichen in StringList laden?
 
Zitat:

Zitat von SneakyBagels (Beitrag 1375946)
Also ich weiß nicht was ich antworten soll, denn das habe ich doch schon zweimal geschrieben was gesucht wird :roll:
Das Problem ist ja aber schon gelößt.

Wie erkläre ich das jetzt, dass du es verstehst?

Also...diese Lösung führt dich auf deinem Rechner zum Ziel. So weit so gut.
Da du daraus ja so ein großes Geheimnis machst, kann man nur raten was du eigentlich möchtest.
Ich vermute, du möchtest die Jump Listen auslesen, um dort nach Recent- oder Frequent-Items zu suchen.
Bedenke aber, das diese Lösung höchstwahrscheinlich nur auf deinem Computer funktioniert.
Bspw. gibt es in meinen CustomDestinations-Folder keine Datei mit den Namen 27932e73jddafda77b.customDestinations-ms.
Dafür aber 39 andere Dateien mit der Endung *.customDestinations-ms. Woher weißt du, welche die richtige ist?
Wahrscheinlich ist es nur ein Basteltool für dich selbst. Dann ist das okay. Wenn du aber nach einer allgemeinen Lösung suchst, die auch auf anderen Rechnern bei anderen Benutzern funktionieren soll, dann musst du nochmal in dich gehen und uns genau sagen WAS du suchst und WOZU.

SneakyBagels 4. Jul 2017 13:18

AW: Datei mit Steuerzeichen in StringList laden?
 
Zitat:

Wie erkläre ich das jetzt, dass du es verstehst?
Ich bin nicht dumm, danke.

Zitat:

Bspw. gibt es in meinen CustomDestinations-Folder keine Datei mit den Namen 27932e73jddafda77b.customDestinations-ms.
Schon einmal daran gedacht, dass ich da irgendeinen Quatsch hingetippt haben könnte nur um ein Beispiel zu geben?

Zitat:

Wenn du aber nach einer allgemeinen Lösung suchst, die auch auf anderen Rechnern bei anderen Benutzern funktionieren soll, dann musst du nochmal in dich gehen und uns genau sagen WAS du suchst und WOZU.
Steht im ersten Beitrag. Und was Uwe empfohlen hat ist genau das was ich gesucht habe.

Zitat:

Zitat von Uwe Raabe (Beitrag 1375947)
Falls du auf das Uppercase ganz verzichten könntest, wäre das natürlich noch besser.

Habe es eben entfernt. Funktioniert alles wunderbar.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:39 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz