AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi TPath.Combine, TPath.GetTempPath threadsicher?
Thema durchsuchen
Ansicht
Themen-Optionen

TPath.Combine, TPath.GetTempPath threadsicher?

Ein Thema von zeras · begonnen am 28. Dez 2014 · letzter Beitrag vom 29. Dez 2014
Antwort Antwort
Seite 1 von 3  1 23      
zeras

Registriert seit: 11. Mär 2007
Ort: Saalkreis
1.633 Beiträge
 
Delphi 12 Athens
 
#1

TPath.Combine, TPath.GetTempPath threadsicher?

  Alt 28. Dez 2014, 16:43
Delphi-Version: XE5
Ich nutzte folgenden Code, um eine Resource in das Filesystem zu schreiben.
Da alles im Hintergrund laufen soll, habe ich das in einen Thread gepackt.
Leider bricht mir dann mein Tablet mit Meldung "Anwendung wurde beendet" nach einiger Zeit ab.
Ich habe dann testweise TPath.GetTempPath gegen den Pfad als String getauscht und nun scheint es zu laufen.
Ist denn TPath eine visuelle Komponente, oder wie kann man sich das Problem erklären?

Delphi-Quellcode:
//kopiert einen Song als Resource in eine Datei
Function CopyStream2File(ResourceID: string; var fName: String): boolean;
var
  ResStream: TResourceStream;

begin
  Result := False;

  ResStream := TResourceStream.Create(HInstance, ResourceID, RT_RCDATA);

  try

    //MP3 File aus Resource laden und in Filesystem ablegen
    fName := TPath.Combine(TPath.GetTempPath, 'tmp.mp3');
// fName := TPath.Combine('/data/data/com.embarcadero.Meinprogram/files/', 'tmp.mp3');

    ResStream.Position := 0;
    ResStream.SaveToFile(fName);
    Result := True;
  finally
    ResStream.Free;
  end;
end;
Matthias
Es ist nie falsch das Richtige zu tun!
- Mark Twain
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.993 Beiträge
 
Delphi 12 Athens
 
#2

AW: TPath.Combine, TPath.GetTempPath threadsicher?

  Alt 28. Dez 2014, 22:37
TPath.GetTempPath selber ist threadsave, aber wie es mit MSDN-Library durchsuchenGetTempPath und MSDN-Library durchsuchenGetLongPathName aussieht, kann ich nicht sagen.

Aber warum kommt keiner auf die Idee diesen Wert in einer globalen Veriable zwischenzuspeichern
oder kann es denn passieren, daß sich dieser Wert jemals ändern wird?



Und was sind das für Threads und wie behandelst du die Exceptions darin?


PS:
Warum ist fName ein VAR-Parameter?
Und Result=False wird es niemals geben.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.142 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: TPath.Combine, TPath.GetTempPath threadsicher?

  Alt 29. Dez 2014, 12:37

PS:
Warum ist fName ein VAR-Parameter?
Und Result=False wird es niemals geben.
GlaskugelMode.Active := true;

Damit man außen in einem Log FName ausgeben kann.
Klar gibt es Result=false... bei einer Exception.

GlaskugelMode.Active := false;
  Mit Zitat antworten Zitat
zeras

Registriert seit: 11. Mär 2007
Ort: Saalkreis
1.633 Beiträge
 
Delphi 12 Athens
 
#4

AW: TPath.Combine, TPath.GetTempPath threadsicher?

  Alt 29. Dez 2014, 12:52
Aber warum kommt keiner auf die Idee diesen Wert in einer globalen Veriable zwischenzuspeichern
oder kann es denn passieren, daß sich dieser Wert jemals ändern wird?
Das war eine Funktion, die ich erst mal aus einem Beispiel genommen hatte. Die Idee, den Wert in eine globalen Variable zu speichern, ist gar nicht so schlecht, aber ich wollte erst mal das Beispiel zum Fliegen bringen. Danach wäre ich (oder vielleicht auch nicht) auf die Idee gekommen, das ganze zu optimieren.

Damit man außen in einem Log FName ausgeben kann.
Nicht ganz, aber ich möchte die Datei dann über den Mediaplayer abspielen und so brauche ich den Namen mit Pfadangabe.

Klar gibt es Result=false... bei einer Exception.
So ganz falsch ist doch dieser Teil nicht oder? Wenn ich den Stream nicht speichern kann, ist die Abfrage false und es wird dann in der aufrufenden Funktion nicht weiter gemacht. Es nützt ja nichts, wenn keine MP3 Datei da ist, dass ich dann den Mediaplayer anwerfe.
Matthias
Es ist nie falsch das Richtige zu tun!
- Mark Twain
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.142 Beiträge
 
Delphi 10.3 Rio
 
#5

AW: TPath.Combine, TPath.GetTempPath threadsicher?

  Alt 29. Dez 2014, 13:18
Klar gibt es Result=false... bei einer Exception.
So ganz falsch ist doch dieser Teil nicht oder? Wenn ich den Stream nicht speichern kann, ist die Abfrage false und es wird dann in der aufrufenden Funktion nicht weiter gemacht. Es nützt ja nichts, wenn keine MP3 Datei da ist, dass ich dann den Mediaplayer anwerfe.
Nein, das ist richtig, aber ein Try Finally fängt keine Exception ab...
Also könntest Du außen die Exception abfangen und Result weg lassen oder must noch ein try except drum setzen.

Mavarik
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.421 Beiträge
 
Delphi 12 Athens
 
#6

AW: TPath.Combine, TPath.GetTempPath threadsicher?

  Alt 29. Dez 2014, 13:24
Klar gibt es Result=false... bei einer Exception.
So ganz falsch ist doch dieser Teil nicht oder? Wenn ich den Stream nicht speichern kann, ist die Abfrage false und es wird dann in der aufrufenden Funktion nicht weiter gemacht. Es nützt ja nichts, wenn keine MP3 Datei da ist, dass ich dann den Mediaplayer anwerfe.
Eben nicht! Da die Exception innerhalb der Function nicht durch ein except abgefangen wird, gelangt sie an den nächsthöheren try-finally bzw. try-except Block. Damit wird die Auswertung der Funktionsrückgabe gar nicht ausgeführt.

Soll also bei einer auftretenden Exception lediglich ein false zurückgegeben werden, würde sich dieses Konstrukt anbieten:

Delphi-Quellcode:
//kopiert einen Song als Resource in eine Datei
Function CopyStream2File(ResourceID: string; var fName: String): boolean;
var
  ResStream: TResourceStream;

begin
  try
    ResStream := TResourceStream.Create(HInstance, ResourceID, RT_RCDATA);

    try

      //MP3 File aus Resource laden und in Filesystem ablegen
      fName := TPath.Combine(TPath.GetTempPath, 'tmp.mp3');

      ResStream.Position := 0;
      ResStream.SaveToFile(fName);
      Result := True;
    finally
      ResStream.Free;
    end;
  except
    result := false;
  end;
end;
Roter Kasten: Wie Mavarik korrekt bemerkt.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.993 Beiträge
 
Delphi 12 Athens
 
#7

AW: TPath.Combine, TPath.GetTempPath threadsicher?

  Alt 29. Dez 2014, 13:32
@GlaskugelMode:

Wie gerade schon jemand sagte:

Es gibt entweder True oder eine Exception.
Bei einer Exception wird mit der Panzerfaust reingeschossen, man fliegt an der Result-Rückgabe vorbei, direkt zum nächsten Try-Except und es gibt somit kein Result.

Im Prinzip funktioniert die gezeigte Lösung, auch wenn es nicht wirklich "optiomal" ist, wenn die Exception so abgefangen, dann einfach verworfen und in einen nichtssagenden Boolean verwandelt wird.

* Exception abfangen und als Boolean zurückgeben, dann aber bitte mit Zusatzinfox ala GetLastError
* oder als Fehlercode zurückgeben (die Fehler/Exception sprechend umwandeln)
* oder eben ohne Fehlerrückgabe-Wert und dafür mit Exceptions arbeiten

[add]
Lach .... die RedBox lebt mal wieder
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (29. Dez 2014 um 13:37 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.142 Beiträge
 
Delphi 10.3 Rio
 
#8

AW: TPath.Combine, TPath.GetTempPath threadsicher?

  Alt 29. Dez 2014, 13:34
eben doch
Zum Beispiel so:

Delphi-Quellcode:
Function CopyStream2File(ResourceID: string; var fName: String): boolean;
var
   ResStream: TResourceStream;

begin
  Result := False;
   
  try

   ResStream := TResourceStream.Create(HInstance, ResourceID, RT_RCDATA);

   try

     //MP3 File aus Resource laden und in Filesystem ablegen
     fName := TPath.Combine(TPath.GetTempPath, 'tmp.mp3');
// fName := TPath.Combine('/data/data/com.embarcadero.Meinprogram/files/', 'tmp.mp3');

     ResStream.Position := 0;
     ResStream.SaveToFile(fName);
     Result := True;
   finally
     ResStream.Free;
   end;
  except
  end
end;
oder
Delphi-Quellcode:
var
  FName : String;
  error : boolean;
begin
  ...
  try
    error := CopyStream2File('42',FName);
  except
    MyError('Fehler...');
  end;

  if not Error then
    Play(FName)
  
end;

Geändert von Mavarik (29. Dez 2014 um 13:43 Uhr)
  Mit Zitat antworten Zitat
zeras

Registriert seit: 11. Mär 2007
Ort: Saalkreis
1.633 Beiträge
 
Delphi 12 Athens
 
#9

AW: TPath.Combine, TPath.GetTempPath threadsicher?

  Alt 29. Dez 2014, 13:36
Ich habe nun eure Meinungen verstanden und etwas dazugelernt.
Aber was hat es mit dem roten Kasten auf sich?
Matthias
Es ist nie falsch das Richtige zu tun!
- Mark Twain
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.142 Beiträge
 
Delphi 10.3 Rio
 
#10

AW: TPath.Combine, TPath.GetTempPath threadsicher?

  Alt 29. Dez 2014, 13:38
Aber was hat es mit dem roten Kasten auf sich?
Immer wenn einer schneller war mit seinem Posting... Während Du noch geschrieben hast.
(Na, wer hatte Ihn dieses mal?)


So wäre wahrscheinlich die bevorzugte Lösung:
Delphi-Quellcode:
Function CopyStream2File(ResourceID: string): String;
var
    ResStream: TResourceStream;
begin
    ResStream := TResourceStream.Create(HInstance, ResourceID, RT_RCDATA);
    try
      //MP3 File aus Resource laden und in Filesystem ablegen
      Result := TPath.Combine(TPath.GetTempPath, 'tmp.mp3');

      ResStream.Position := 0;
      ResStream.SaveToFile(fName);
    finally
      ResStream.Free;
    end;
end;


var
   FName : String;
begin
   try
     FName := CopyStream2File('42');
     Play(FName);
   except
   end;
end;
Auch wenn ich es immer so mache wie in meinen 1. Posting...

Mavarik

Geändert von Mavarik (29. Dez 2014 um 13:45 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:50 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz