Inhaltsverzeichnis

6.12.0 Temporäre Verzeichnisse und temporäre Dateien

Ein temporäres Verzeichnis dient zur zeitlich begrenzten Speicherung von Dateien. Temporäre Dateien nutzen Sie zur zeitlich begrenzten Speicherung von Daten. Temporäre Verzeichnisse und temporäre Dateien werden nach dem Gambas-Programm-Ende vom Betriebssystem automatisch gelöscht.

Wenn Sie zum Beispiel Ihre Scans in TIFF-Dateien archivieren, um sie später in das PNG- oder JPG-Format zu konvertieren, dann bietet es sich an, eine Auswahl an TIFF-Dateien in ein temporäres Verzeichnis zu kopieren und diese dann zu konvertieren. Beenden Sie abschließend Ihr Gambas-Konvertierungsprogramm, dann werden die ausgewählten TIFF-Dateien im temporären Verzeichnis und auch das temporäre Verzeichnis automatisch gelöscht.

Benötigt werden temporäre Dateien, wenn Sie etwa ein Bash-Skript in einem Gambas-Programm verwenden wollen und das Skript script.sh im Projekt-Ordner in einem Verzeichnis data liegt. Rufen Sie nach dem Start der ausführbaren Datei *.gambas das Skript zur Laufzeit auf, endet das mit einer Fehlermeldung, da Sie keine Berechtigung haben, das Skript auszuführen. Der Grund liegt darin, dass alle Dateien im Gambas-Archiv *.gambas nur gelesen werden können! Ein Ausweg mit dem Einsatz einer temporären Datei, die Sie lesen und ausführen können, wird im Folgenden kurz skizziert:

Public sScriptPath As String
Public sTempScriptPath As String
Public sStore As String
 
Public Sub Form_Open()
 
  sScriptPath = "./data/test_script.sh"               ' Pfad zum Skript (Orginal) festlegen
  sTempScriptPath = Temp(File.BaseName(sScriptPath))  ' Pfad zu einer temporären Datei festlegen
  Copy sScriptPath To sTempScriptPath                 ' Original-Skript in temporäre Datei kopieren 
 
  Chmod sTempScriptPath To "r-xr-xr-x"                ' Ausführungsrechte für die Kopie setzen
' Chmod sTempScriptPath To "..x..x..x"                ' Alternative
 
End
 
Public Sub btnRunScript_Click()
  Shell sTempScriptPath To sStore                     ' Skript-Kopie in einer Shell-Instruktion ' mit den erforderlichen Rechten ausführen ...
End

Die temporäre Datei /tmp/gambas.1000/<PID>/test_script.tmp – mit der gearbeitet wurde – wird nach dem Programm-Ende automatisch gelöscht.

6.12.0.1 Funktionen Temp() und Temp$()

File name = Temp$( [ Prefix ] )
File name = Temp( [ Prefix ] )

Die Funktionen Temp() und Temp$() geben den Pfad für eine temporäre Datei oder ein temporäres Verzeichnis zurück. Der Pfad hat die folgende Form:

/tmp/gambas.<UserID>/<ProcessID>/<Prefix>.tmp

Wenn kein Präfix angegeben ist, wird er durch eine Ganzzahl ersetzt, die bei jedem weiteren Aufruf dieser Funktion automatisch erhöht wird. Auf diese Weise ist der zurückgegebene Pfad-Name immer eindeutig. Diese Funktion gibt nur einen Pfad zurück. Sie können anschließend diesen Pfad verwenden, um zum Beispiel eine Datei, ein Verzeichnis, einen Unix-Socket oder einen Symlink temporär zu erzeugen.

Wichtig zu wissen:

Beispiel:

  Dim sTempDir As String = Temp$()
 
  Mkdir sTempDir
 
' Entpackt ein Archiv in das angelegte temporäre Verzeichnis.
  Exec ["tar" "-zxf", "<path_to_archiv>/archive.tar.gz", "-C", sTempDir] Wait
 
' Erzeugt die Instruktion EXEC [..] einen Fehler, werden Sie so informiert:
  If Process.LastValue Then Print Error.Code
  ...

Mit diesem Quelltext-Abschnitt

' Gambas class file
 
Public Sub btnStart_Click()
 
  Dim sRuntimeDir, sTempDir As String
 
  txaResults.Clear()
  txaResults.Insert(gb.Lf)
' 1. Call of the function Temp$()
  sTempDir = Temp$()
  txaResults.Insert("File-Path 1  = " & sTempDir & gb.Lf)
  File.Save(sTempDir, "1")
 
' 2. Call of the function Temp() - alternative syntax
  sTempDir = Temp()
  txaResults.Insert("File-Path 2  = " & sTempDir & gb.Lf) ' 2. Aufruf der Funktion mit alternativer Syntax 
  File.Save(sTempDir, "2")
 
' 3. Call of the function Temp(...) with default of a freely defined file name 'test'
  sTempDir = Temp$("test")
  txaResults.Insert("File-Path 3  = " & sTempDir & gb.Lf)
  File.Save(sTempDir, "3")
 
' 4. Creation of the file with the path /tmp/gambas.1000/<PID>/link.tmp and the content "gambas-book.net"
  sTempDir = Temp$("content")
  txaResults.Insert("File-Path 4  = " & sTempDir & gb.Lf)
  File.Save(sTempDir, "gambas-book.net") ' Datei
  txaResults.Insert("File-Content = " & File.Load(sTempDir) & gb.Lf)
 
' 5. Creation of a file in a special temporary directory
  sRuntimeDir = Desktop.RuntimeDir &/ "time.txt"
  txaResults.Insert("File-Path 5  = " & sRuntimeDir & gb.Lf)
  File.Save(sRuntimeDir, Date.ToUnixTime(Now())) ' File
  txaResults.Insert("Unix Timestamp = " & File.Load(sRuntimeDir) & gb.Lf)
  txaResults.Insert("Date from Timestamp = " & Date.FromUnixTime(File.Load(sRuntimeDir)) & gb.Lf)
 
' 6. Creation of an empty text file in a temporary directory
  sTempDir = File.Dir(Temp()) &/ "gambas-book"
  If Exist(sTempDir) Then 
     DeleteDirRecursively(sTempDir)
     Rmdir sTempDir
  Endif
' If Exist(sTempDir) Then Shell.RmDir(sTempDir) ' Effective alternative!
 
  Shell.MkDir(sTempDir)
  File.Save(sTempDir &/ "values.log", "")
  txaResults.Insert("File-Path 6  = " & sTempDir &/ "values.log" & gb.Lf)
 
End
 
Public Sub DeleteDirRecursively(sDir As String)
 
  Dim sFile, sDirectory As String
 
  For Each sFile In RDir(sDir, "*")
    If Not IsDir(sFile) Then
     ' Print "File-Path: ", sDir &/ sFile
       Kill sDir &/ sFile
    Endif
  Next
 
  For Each sDirectory In RDir(sDir, "*", gb.Directory)
  ' Print "Folder: ", sDirectory
    Rmdir sDirectory
  Next
 
End 

ergeben sich diese Ausgaben:

B1

Abbildung 6.12.0.1.1: Ergebnisse 1

Bei einem weiteren Start ergeben sich neue temporäre Dateien sowie geänderte Inhalte:

B2

Abbildung 6.12.0.1.2: Ergebnisse 2

Das Besondere im Quelltext ist die Löschung des temporären Verzeichnisses mit den alternativen Ansätzen über Shell.RmDir(sTempDir) und die Prozedur DeleteDirRecursively(sDir As String).

6.12.0.2 Exkurs: Eigenschaft Desktop.RuntimeDir (gb.desktop)

Das Verzeichnis /run ist ein virtuelles, temporäres Dateisystem (https://de.wikipedia.org/wiki/Tmpfs). Es existiert im Arbeitsspeicher und wird automatisch geleert, wenn der Computer neu gestartet wird. Die Umgebungsvariable $XDG_RUNTIME_DIR definiert einen guten Platz für Ihre Laufzeit-Dateien. Es ist das Verzeichnis /run/user/<user-id>, wenn die Umgebungsvariable $XDG_RUNTIME_DIR auf den Standardwert gesetzt ist. Es scheint, als ob /run/user/<user-id> dem /tmp-Verzeichnis Konkurrenz macht. Offensichtlich scheint /run moderner zu sein, wie es die Beschreibung auf https://unix.stackexchange.com/questions/13972/what-is-this-new-run-filesystem/13983#13983 andeutet. Es ist sicher ein guter Plan, wenn jeder Benutzer unter /run/user/<user-id> von vorn herein sein eigenes (temporäres) Verzeichnis hat.

$ echo $XDG_RUNTIME_DIR
/run/user/1000

Obwohl Gambas gegenwärtig mit Temp$() nur /tmp unterstützt und sein „gambas.<user-id>“ selbst erzeugt haben Sie auch Zugriff auf das (Basis-)Verzeichnis /run/user/1000. Sie erhalten als Benutzer Zugriff über den Wert der Eigenschaft Desktop.RuntimeDir (gb.desktop). Diese Eigenschaft (Datentyp String) gibt das Basis-Verzeichnis zurück, in dem benutzerspezifische, aber nicht zwingend zur Laufzeit benötigte Daten und andere Stream-Objekte wie zum Beispiel Unix-Sockets oder benannte Pipes (Named Pipes) gespeichert werden sollen. Der Benutzer muss mit Unix-Zugriffsmodus 0700 der einzige sein, der vollen Zugriff auf das Verzeichnis /run/user hat - was schnell geprüft werden kann:

hans@mint-183 ~ $ cd /run/user
hans@mint-183 /run/user $ ls -l
insgesamt 0
drwx------ 7 hans hans 180 Aug 24 10:37 1000

Weitere Hinweise finden Sie im Kapitel ´6.1 Pfade in Gambas´.

Download