Autor Beitrag
Popov
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 1655
Erhaltene Danke: 13

WinXP Prof.
Bei Kleinigkeiten D3Pro, bei größeren Sachen D6Pro oder D7
BeitragVerfasst: Di 03.02.04 02:41 
Hin und wieder braucht man einen automatisch generierten Dateinamen. Er soll wenn's geht alphabetisch sortierbar sein und nicht zwei mal vorkommen. Mit den Jahren hab ich einige Funktionen geschrieben, die für jede Gelegenheit einen Namen generieren. Es gibt keine Funktion die alles kann. Die Eine erstellt einen Namen aus max. acht Zeichen, die Andere erstellt in der Sekunde bis 1000 verschiedene Namen und dann gibt es welche, die erstellen die Namen so wie es auch der Explorer macht (z.B. "Neuer Ordner (2)"). Die Funktionen sind fertig einsetztbar, können aber auch noch an eigene Bedürfnisse angepasst werden.

Hier die Liste der Funktionen:
  1. DateTimeShortFileName - Erstellt einen kurzen 8 Zeichen Namen für DOS aus Zeit;
  2. DateTimeShortFileNamePlus - Erstellt einen kurzen 8.3 Zeichen Namen für DOS aus Zeit;
  3. DateTimeFileName - Erstellt einen langen Dateinamen aus Zeit;
  4. NewFileNameA - Erstellt einen einmaligen Dateinamen im Ordner (Variante 1);
  5. NewFileNameB - Erstellt einen einmaligen Dateinamen im Ordner (Variante 2);
  6. GetTempFile - Erstellt einen Temp-Dateinamen im Temp-Ordner mit Pfad;
  7. GetFileNameA - Erstellt einen max. 8 Zeichen langen Dateinamen mit Pfad;
  8. GetFileNameB - Erstellt einen max. 8 Zeichen langen Dateinamen mit Pfad;

Wie gesagt, jede Funktion hat ihre Vor- und Nachteile.


DateTimeShortFileName

Erstellt einen Dateinamen aus Datum und Zeit. Der Name ist 8 Zeichen lang, also als 8.3 DOS-Name verwendbar und kann alphabetisch sortiert werden, d.h. der neuste Name ist immer am Ende der Liste. Nachteil ist, das max. ein einmaliger Name pro Sekunde generiert werden kann, d.h. man muß eventuell, wenn die Möglichkeit besteht, daß die Funktion in der Sekunde mehrmals aufgerufen wird, in einer Schleife prüfen ob der Name bereits vergeben ist.

Der Name besteht also aus acht Zeichen. Der Pfad und die Dateierweiterung müssen selbst angefügt werden. Liefert einen Namen in der Form:

  • 31af1640

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
function DateTimeShortFileName: String;
  function F(Value: Integer): String;
  begin
    Result := FormatFloat('00', Value);
  end;
const
  abc = '0123456789abcdefghijklmnopqrstuvwxyz';
var
  Year, Month, Day, Hour, Min, Sec, MSec: Word;
begin
  DecodeDate(Now, Year, Month, Day);
  DecodeTime(Now, Hour, Min, Sec, MSec);
  if Year > 2000 then Year := Year - 2000;

  Result := Format('%s%s%s%s%s%s', [abc[Year], abc[Month], abc[Day],
    abc[Hour + 1], F(Min), F(Sec)]);
end{Popov}



DateTimeShortFileNamePlus

Funktion wie DateTimeShortFileName, mit den Unterschied, daß hier auch die Erweiterung generiert wird. Dadurch sind auch mehrere Dateinamen in der Sekunde möglich, die 8.3 DOS Kompatibel sind. Der Nachteil dieser Funktion ist, daß die Erweiterung nicht genutzt werden kann. Diese Funktion kann also nur dann benutzt werden, wenn die Erweiterung keine Rolle spielt.

Der Name besteht aus acht-plus-drei Zeichen. Der Pfad muß selbst angefügt werden. Liefert einen Namen in der Form:

  • 31af1640.990

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
function DateTimeShortFileNamePlus: String;
  function F(Value, Count: Integer): String;
  begin
    Result := FormatFloat(Copy('000'1, Count), Value);
  end;
const
  abc = '0123456789abcdefghijklmnopqrstuvwxyz';
var
  Year, Month, Day, Hour, Min, Sec, MSec: Word;
begin
  DecodeDate(Now, Year, Month, Day);
  DecodeTime(Now, Hour, Min, Sec, MSec);
  if Year > 2000 then Year := Year - 2000;

  Result := Format('%s%s%s%s%s%s.%s', [abc[Year], abc[Month], abc[Day],
    abc[Hour + 1], F(Min,2), F(Sec,2), F(MSec, 3)]);
end{Popov}



DateTimeFileName

Das ist ein Datum und Zeit Dateiname, der mit Windows 95 langen Dateinamen kompatibel ist. Der Name besteht aus mindestens 15 Zeichen (es können noch Formatierungszeichen eingefügt werden) und ist alphabetisch sortierbar. Es können bis 1000 Namen in der Sekunde generiert werden. Wenn also ein Name unter Windows generiert werden muß, der auch noch alphabeisch sortierbar sein soll und aus dem man das Datum auslesen kann, dann ist das die perfekte Funktion.

Der Name besteht also aus 15+ Zeichen. Der Pfad und die Dateierweiterung müssen selbst angefügt werden. Liefert einen Namen in der Form:

  • 040203-164532-153

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
function DateTimeFileName: String;
  function F(Value, Count: Integer): String;
  begin
    Result := FormatFloat(Copy('000'1, Count), Value);
  end;
var
  Year, Month, Day, Hour, Min, Sec, MSec: Word;
begin
  DecodeDate(Now, Year, Month, Day);
  DecodeTime(Now, Hour, Min, Sec, MSec);
  if Year > 2000 then Year := Year - 2000;

  Result := Format('%s%s%s-%s%s%s-%s', [F(Year,2), F(Month,2), F(Day,2), {Datum}
    F(Hour,2), F(Min,2), F(Sec,2), F(MSec,3)]); {Zeit + MSec}
end{Popov}



NewFileNameA

Generiert einen einmaligen Dateinamen im Ordner, in dem er an den Dateinamen eine Zahl in Klammern anhängt. Existiert bereits ein "C:\AutoExec.bat", dann liefert die Funktion ein "C:\AutoExec (1).bat". Als nächstes dann"C:\AutoExec (2).bat" usw. Diese Funktion prüft also ob der Name bereits existiert und erweitert ihm durch einem Zahlen-Sufix. Dieser Dateiname ist nicht alphabetisch sortierbar, da ein (19) alphabeisch kleiner ist wie (2).

Der Name besteht aus dem alten Dateinamen - es wird nur eine Zahl in einer Klammer hinzugefügt. Der Pfad und die Dateierweiterung bleiben erhalten. Liefert einen Namen in der Form:

  • C:\Neue Textdatei (2).txt

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
function NewFileNameA(FileName: String): String;
var
  k: Integer;
begin
  Result := FileName;
  k := 0;
  while FileExists(Result) do
  begin
    Inc(k);
    Result := Copy(FileName, 1, LastDelimiter('.', FileName) - 1) +
              Format(' (%d)', [k]) + ExtractFileExt(FileName);
  end;
end{Popov}



NewFileNameB

Ist die gleiche Funktion wie die Funktion NewFileNameA, jedoch mit dem Unterschied, daß hier eine mehrstellige und formatierte Zahl angefügt wird und nicht eine Zahl in Klammern. Dieser Dateiname kann also alphabetisch sortiert werden.

Der Name besteht also aus dem alten Dateinamen - es wird nur eine formatierte Zahl hinzugefügt. Der Pfad und die Dateierweiterung bleiben erhalten. Liefert einen Namen in der Form:

  • C:\Dateiname000001.txt

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
function NewFileNameB(FileName: String): String;
var
  k: Integer;
begin
  Result := FileName;
  k := 0;
  while FileExists(Result) do
  begin
    Inc(k);
    Result := Copy(FileName, 1, LastDelimiter('.', FileName) - 1) +
              FormatFloat('000000', k) + ExtractFileExt(FileName);
  end;
end{Popov}



GetTempFile

Erstellt einen einmaligen Dateinamen im Temp-Ordner. Der Name und Erweiterung werden in dieser Funktion automatisch generiert. Durch Änderung der Funktion kann man einen Einfluß auf die ersten drei Buchstaben nehmen. Der Name ist nicht alphabetisch, ist aber DOS 8.3 kompatibel.

Ein Nachteil bei dieser Funktion ist, daß gleich eine leere Datei mit dem Namen erstellt wird. Wenn sie nicht erwünscht ist, dann muß man sie mit DeleteFile wieder löschen. Aber das ist nicht so ohne weiteres (bzw. so schnell) möglich.

Das Problem ist, daß es einige Zeit kostet bis das Sytem die Datei erstellt hat. Das dauert nicht lange, aber länger als daß man es mit "if FileExists" gleich abfragen könnte. Will man also die Datei wieder löschen, dann muß man eine Zeit warten bevor man mit "if FileExists" fragt. Das könnte man z.B. mit einer While Schleife machen. Kann man die Datei nicht gebrauchen oder es ist zu kompliziert die Datei zu entfernen, dann sollte man sich überlegen diese Funktion einzusetzten.

Der Name und Pfad werden automatisch generiert. Als Pfad wird der System-Temp-Order genommen. Bei Fehler wird ein Nullstring (#0) zurückgegeben. Liefert einen Namen in der Form:

  • C:\Windows\Temp\~tm456.TMP

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
function GetTempFile: String;
var
  TempPath: array[0..MAX_PATH+1of Char;
  Buffer: array[0..MAX_PATH+1of Char;
  i: Integer;
begin
  Result := #0;

  if GetTempPath(MAX_PATH, TempPath) <> 0 then
    if GetTempFileName(TempPath, '~tm'0, Buffer) <> 0 then
      Result := Buffer;

  //Hinweis: GetTempFileName erstellt auch gleich eine leere Datei.
end{Popov}


Löschen kann man die Datei in dem man z.B. diesen Code als letzte Zeile einsetzt:

ausblenden Delphi-Quelltext
1:
  while FileExists(Result) do DeleteFile(Result);					


Nur vorsicht! Hier muß man sich sicher sein, daß das System die Datei wirklich anlegen wird, sonnst wird das eine Endlosschleife.


GetFileNameA

Ist fast wie GetTempFile, mit dem Unterschied, daß man hier einen Pfad angeben kann. Weiterhin kann man einen Namenpräfix von drei Buchstaben angeben. Es wird hier ein einmaliger Dateiname im Pfad generiert. Er ist DOS 8.3 kompatibel, jedoch nicht alphabetisch.

Ein Nachteil bei dieser Funktion ist, daß gleich eine leere Datei mit dem Namen erstellt wird. Wenn sie nicht erwünscht ist, dann muß man sie mit DeleteFile wieder löschen. Ansonsten gilt das gleiche wie oben.

Der Name wird automatisch generiert. Als Pfad wird der angegebene Order genommen. Bei Fehler wird ein Nullstring (#0) zurückgegeben. Liefert einen Namen in der Form:

  • C:\aut456.TMP

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
function GetFileNameA(Path, Prefix: String): String;
var
  Buffer: array[0..MAX_PATH+1of Char;
  i: Integer;
begin
  Result := #0;
  if Path[Length(Path)] <> '\' then Path := Path + '\';

  if not DirectoryExists(Path) then Exit;

  if GetTempFileName(PChar(Path), PChar(Prefix), 0, Buffer) <> 0 then
    Result := Buffer;

  //Hinweis: GetTempFileName erstellt auch gleich eine leere Datei.
end{Popov}


Löschen kann man die Datei in dem man z.B. diesen Code als letzte Zeile einsetzt:

ausblenden Delphi-Quelltext
1:
  while FileExists(Result) do DeleteFile(Result);					


Nur vorsicht! Hier muß man sich sicher sein, daß das System die Datei wirklich anlegen wird, sonnst wird das eine Endlosschleife.

Beispiel:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage(GetFileNameA('c:''aut'));
end;



GetFileNameB

Eine Abwandlung von GetFileNameA. Auch hier wird der Dateiname durch die System Funktion GetTempFileName generiert, jedoch ohne daß eine Datei angelegt wird. Die Funktion Prüft ob der Name bereits vergeben ist. Das Ergebnis ist ein Dateiname mit einem Pfad und einer eigenen Dateierweiterung. Man kann hier einen Namenpräfix von drei Buchstaben angeben; der Rest wird generiert. Es wird ein einmaliger Dateiname im Pfad generiert. Er ist DOS 8.3 kompatibel, jedoch nicht alphabetisch.

Der Name Name wird automatisch generiert. Als Pfad wird der angegebene Order genommen. Bei Fehler wird ein Nullstring (#0) zurückgegeben. Liefert einen Namen in der Form:

  • C:\aut456.abc

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
function GetFileNameB(Path, Prefix, Ext: String): String;
var
  Buffer: array[0..MAX_PATH+1of Char;
  i: Integer;
  Dummy, MSec: Word;
begin
  Result := #0;
  if Path[Length(Path)] <> '\' then Path := Path + '\';

  if not DirectoryExists(Path) then Exit;

  repeat
    DecodeTime(Now, Dummy, Dummy, Dummy, MSec);
    if MSec = 0 then Dummy := 1;

    if GetTempFileName(PChar(Path), PChar(Prefix), UINT(Dummy * MSec),
      Buffer) <> 0 then Result := ChangeFileExt(Buffer, Ext);
  until not FileExists(Result);
end;


Beispiel:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage(GetFileNameB('c:''aut''.bat'));
end;

_________________
Popov

Für diesen Beitrag haben gedankt: HenryHux