2009-08-27 7 views
11

Wie überprüfe ich, ob ein Verzeichnis in lua existiert, vorzugsweise ohne das LuaFileSystem-Modul zu verwenden, wenn möglich?Prüfen, ob ein Verzeichnis in lua existiert?

Der Versuch, so etwas wie dieses Python Linie zu tun:

os.path.isdir(path) 

Antwort

12

Das Problem ist, dass die Aktien Lua Verteilung (fast) nur Funktionen enthält, die in Standard C angegeben sind. Standard C macht keine Vermutungen über dort tatsächlich ein Dateisystem von einer bestimmten Art da draußen (oder sogar ein Betriebssystem, In diesem Fall stellen die Module os und io keine Zugriffsinformationen zur Verfügung, die in der Standard-C-Bibliothek nicht verfügbar sind.

Wenn Sie versuchen würden, reinen Standard C zu codieren, hätten Sie das gleiche Problem.

Es besteht die Möglichkeit, dass Sie wissen, ob der Ordner implizit existiert, wenn Sie versuchen, ihn zu verwenden. Wenn Sie erwarten, dass es existiert und für Sie schreibbar ist, dann erstellen Sie dort eine temporäre Datei und wenn das gelingt, existiert der Ordner. Wenn dies fehlschlägt, können Sie einen nicht vorhandenen Ordner natürlich nicht von unzureichenden Berechtigungen unterscheiden.

Bei weitem die leichteste Antwort auf eine bestimmte Antwort wäre eine dünne Bindung an nur die betriebssystemspezifischen Funktionsaufrufe, die die benötigten Informationen liefern. Wenn Sie das lua alien Modul akzeptieren, dann können Sie die Bindung in ansonsten reinem Lua machen.

Einfacher, aber etwas schwerer, soll Lua File System akzeptieren. Es bietet ein tragbares Modul, das die meisten Dinge unterstützt, die man über Dateien und das Dateisystem wissen möchte.

5

Nun, die 5.1-Referenzhandbuch hat nichts in the os table, aber wenn Sie Nixstaller verwenden, erhalten Sie os.fileexists für genau das, was Sie erklärt haben .

Wenn Sie ein wenig leisten können, hantieren, oder wenn Sie wissen, was OS Sie werde laufen, könnte man mit dem Standard-os Bibliothek weg os.execute mit einigen Systemaufruf, wenn die Datei vorhanden ist identifiziert.

Noch besser als os.execute os.rename werden:

os.rename(oldname, newname)

Benennt Datei oldname-newname benannt. Wenn diese Funktion fehlschlägt, gibt sie Null zurück, plus eine Zeichenfolge, die den Fehler beschreibt.

könnten Sie versuchen oldname Einstellung und newname die gleiche - Sie keine Schreibrechte haben könnte, obwohl, so könnte es scheitern, weil man nicht schreiben kann, auch wenn Sie können lesen. In diesem Fall müssten Sie die zurückgegebene Fehlerzeichenfolge analysieren und ableiten, ob Sie schreiben könnten, oder Sie müssten einfach versuchen, die Funktion auszuführen, die eine vorhandene Datei benötigt, und in eine pcall umbrechen.

8

Wenn Sie speziell daran interessiert sind, die LFS-Bibliothek zu vermeiden, verfügt das Lua Posix library über eine Schnittstelle zu stat().

require 'posix' 
function isdir(fn) 
    return (posix.stat(fn, "type") == 'directory') 
end 
+0

Die LuaPosix-Bibliothek ist jedoch viel größer und zwischen Unix und Windows nicht übertragbar. –

0

hier ist ein einfacher Weg, wenn ein Ordner ohne externe BIBLIOTHEK DEPENDENCIES :) existiert zu überprüfen

function directory_exists(path) 
    local f = io.popen("cd " .. path) 
    local ff = f:read("*all") 

    if (ff:find("ItemNotFoundException")) then 
    return false 
    else 
    return true 
    end 
end 

print(directory_exists("C:\\Users")) 
print(directory_exists("C:\\ThisFolder\\IsNotHere")) 

Wenn Sie kopieren und die oben in Lua fügen Sie

false 
true 
sehen sollte

viel Glück :)

+3

Diese Lösung scheint anzunehmen, dass der Benutzer Powershell verwendet ... Das Überprüfen des Rückgabecodes des Befehls cd würde jedoch wahrscheinlich funktionieren. – djs

+0

Ich habe erwartet, dass die Ergebnisse für die erste wahr sind, für die zweite falsch. – RAL

2

Dies ist für die Windows-Plattform getestet. Es ist ganz einfach tatsächlich:

local function directory_exists(sPath) 
    if type(sPath) ~= "string" then return false end 

    local response = os.execute("cd " .. sPath) 
    if response == 0 then 
    return true 
    end 
    return false 
end 

Offensichtlich funktioniert dies möglicherweise nicht auf anderen Betriebssystemen. Aber für Windows-Benutzer, kann dies eine Lösung sein :)

+0

Wenn ich auf Linux und Windows getestet habe, ist 'response'' nil', unabhängig von 'sPath'? – Alex

+0

Es ist in der Regel nicht empfehlenswert, ein externes Programm für eine so einfache Aufgabe aufzurufen, da dies dazu neigt, so viele Probleme wie möglich zu lösen. Auf Unix-ähnlichen Betriebssystemen sollte das Argument 'sPath' in Anführungszeichen gesetzt werden (nicht sicher über Windows) und das ist schwer zu tun. – Lassi

1

Ich benutze diese (aber ich eigentlich für den Fehler überprüfen):

require("lfs") 
-- no function checks for errors. 
-- you should check for them 

function isFile(name) 
    if type(name)~="string" then return false end 
    if not isDir(name) then 
     return os.rename(name,name) and true or false 
     -- note that the short evaluation is to 
     -- return false instead of a possible nil 
    end 
    return false 
end 

function isFileOrDir(name) 
    if type(name)~="string" then return false end 
    return os.rename(name, name) and true or false 
end 

function isDir(name) 
    if type(name)~="string" then return false end 
    local cd = lfs.currentdir() 
    local is = lfs.chdir(name) and true or false 
    lfs.chdir(cd) 
    return is 
end 

os.rename (name1, name2) wird name1 umbenennen Name2. Verwenden Sie den gleichen Namen und nichts sollte sich ändern (außer es gibt einen Badass-Fehler). Wenn alles gut gelaufen ist, wird wahr zurückgegeben, andernfalls gibt es null und die Fehlermeldung zurück. Du hast gesagt, du willst lfs nicht benutzen. Wenn Sie nicht zwischen Dateien und Directorys unterscheiden können, ohne zu versuchen, die Datei zu öffnen (was ein bisschen langsam aber ok ist).

Also ohne LuaFileSystem

-- no require("lfs") 

function exists(name) 
    if type(name)~="string" then return false end 
    return os.rename(name,name) and true or false 
end 

function isFile(name) 
    if type(name)~="string" then return false end 
    if not exists(name) then return false end 
    local f = io.open(name) 
    if f then 
     f:close() 
     return true 
    end 
    return false 
end 

function isDir(name) 
    return (exists(name) and not isFile(name)) 
end 

Es sieht kürzer, aber dauert länger ... Auch eine Datei öffnen, ist ein es riskant, weil der, dass Sie sollte Verwendung LFS. Wenn Sie sich nicht um Leistung (und Fehlerbehandlung -.-) kümmern, können Sie es einfach verwenden.

Viel Spaß beim Programmieren!

+3

'io.open' funktioniert auch mit Verzeichnissen. Sie müssten versuchen, es zusätzlich zu lesen ('f: read (1)'). – blueyed

+0

Danke! Wusste ich nicht! Wäre das nicht auch ein Fehler, wenn die Datei leer ist (wenn ich f: read (1) hinzufüge)? Und AFAIK 'f: read (0)' würde auch nicht helfen ... – tDwtp

0

Für Linux-Benutzer:

function dir_exists(path) 
if type(path) ~= 'string' then 
    error('input error') 
    return false 
end 
local response = os.execute('cd ' .. path) 
if response == nil then 
    return false 
end 
return response 
end 
4

Sie können auch die 'Pfade' Paket verwenden. Here ist der Link zu dem Paket

dann in Lua tun:

require 'paths' 

if paths.dirp('your_desired_directory') then 
    print 'it exists' 
else 
    print 'it does not exist' 
end 
0

Mein bevorzugter Weg, dies in Linux zu tun

if os.execute '[ -e "/home" ]' then 
    io.write "it exists" 
    if os.execute '[ -d "/home" ]' then 
    io.write " and is a directory" 
    end 
    io.write "\n" 
end 

oder ist dies in eine Funktion zu setzen:

6

Dies ist ein Weg, der auf Unix und Windows ohne externe Abhängigkeiten funktioniert:

--- Check if a file or directory exists in this path 
function exists(file) 
    local ok, err, code = os.rename(file, file) 
    if not ok then 
     if code == 13 then 
     -- Permission denied, but it exists 
     return true 
     end 
    end 
    return ok, err 
end 

--- Check if a directory exists in this path 
function isdir(path) 
    -- "/" works on both Unix and Windows 
    return exists(path.."/") 
end 
+1

Sehr clever mit 'os.rename' dafür –