2010-05-14 2 views
4

Если у меня есть этот кодИспользование Lua, проверьте, если файл является каталогом

local f = io.open("../web/", "r") 
print(io.type(f)) 

-- output: file 

как я могу знать, если f указывает на каталог?

+0

Я уверен, что 'f' будет ноль там, как попытка открыть каталог с io.open должен return 'nil' и строка типа' error opening "../web/": это каталог' (в Windows я получаю '../web/: Permission denied') –

ответ

5

Библиотеки Lua по умолчанию не имеют возможности определить это.

Однако вы можете использовать стороннюю библиотеку LuaFileSystem, чтобы получить доступ к более продвинутым взаимодействиям файловой системы; это тоже кросс-платформенный.

+0

Это. Используйте LFS. В советском Lua переносимость вредит ВАМ. – Puppy

9

ANSI C не указывает какой-либо способ получения информации о каталоге, поэтому vanilla Lua не может сообщить вам эту информацию (поскольку Lua стремится к 100-процентной переносимости). Однако для идентификации каталогов вы можете использовать внешнюю библиотеку, такую ​​как LuaFileSystem.

Progamming in Lua даже явно заявляет о пропавшем функциональности каталога:

В качестве более сложного примера, напишем функцию, которая возвращает содержимое данного каталога. Lua не предоставляет эту функцию в своих стандартных библиотеках, потому что ANSI C не имеет функций для этого задания.

Этот пример перемещается, чтобы показать вам, как написать функцию в C самостоятельно.

5

если вы

local x,err=f:read(1) 

, то вы получите "Is a directory" в err.

+0

Ха, это действительно умно. :) – PeterM

+2

Обратите внимание, что сообщение об ошибке (если оно исходит из системы) может быть локализовано, поэтому, вероятно, не очень хорошая идея полагаться на него. –

+0

@ Александр: хороший пункт. – lhf

6

Я нашел этот кусок кода в библиотеке, я использую:

function is_dir(path) 
    local f = io.open(path, "r") 
    local ok, err, code = f:read(1) 
    f:close() 
    return code == 21 
end 

Я не знаю, что код будет в Windows, но на Linux/BSD/OSX он работает отлично.

+0

Это также вернет 'true' для пустых файлов. – blueyed

0
function fs.isDir (file) 
if file == nil then return true end 
if fs.exists(file) then 
    os.execute("dir \""..userPath..file.."\" >> "..userPath.."\\Temp\\$temp") 
    file = io.open(userPath.."\\Temp\\$temp","r") 
    result = false 
    for line in file:lines() do 
     if string.find(line, "<DIR>") ~= nil then 
      result = true 
      break 
     end 
    end 
    file:close() 
    fs.delete("\\Temp\\$temp") 
    if not (result == true or result == false) then 
     return "Error" 
    else 
     return result 
    end 
else 
    return false 
end 
end 

Это код, который я вытащил из библиотеки, которую я нашел ранее.

+0

У вас есть ссылка на библиотеку? Благодарю. – Michael

+0

К сожалению нет, я этого не делаю. Но я обнаружил, что если вы изменяете переменную userPath в каталог, в котором находится ваш проект, создайте папку Temp и используйте ее, не должно быть никаких ошибок вообще. – Marumaru

+0

hmmm - как вы можете что-то вытащить из библиотеки и не знать, откуда вы ее взяли? вы всегда должны давать кредит, где кредит. – Michael

0

Это проверяет сначала, если путь может быть прочитан (который также является nil для пустых файлов), а затем проверяет, что размер не равен 0 дополнительно.

function is_dir(path) 
    f = io.open(path) 
    return not f:read(0) and f:seek("end") ~= 0 
end 
2

По крайней мере, для UNIX:

if os.execute("cd '" .. f .. "'") 
then print("Is a dir") 
else print("Not a dir") 
end 

:)

Смежные вопросы