Lua существует ли файл
So far, we’ve learned a lot about working with data within a program, and how to include more Lua into a program, but not how to import and export data from a file. Lua has plenty of builtin features to handle this via the I/O Library. The I/O library works with both text and binary files.
Lua is Unicode agnostic. This means that all strings are treated effectively as binary data rather than any kind of encoding. Because of this, you rarely need to use a Unicode library except for more specific use cases.
15 Answers 15
but note that this code only tests whether the file can be opened for reading.
Using plain Lua, the best you can do is see if a file can be opened for read, as per LHF. This is almost always good enough. But if you want more, load the Lua POSIX library and check if posix.stat( path ) returns non- nil .
I will quote myself from here
I use these (but I actually check for the error):
os.rename(name1, name2) will rename name1 to name2. Use the same name and nothing should change (except there is a badass error). If everything worked out good it returns true, else it returns nil and the errormessage. If you dont want to use lfs you cant differentiate between files and directories without trying to open the file (which is a bit slow but ok).
So without LuaFileSystem
It looks shorter, but takes longer. Also open a file is a it risky
Have fun coding!
@carpii If you try to open a locked file and read from it it may result in an error (you still want to know whether its a file or not). Same goes for directories (if diectory lock is supported on the host).
@HenrikErlandsson What do you mean? With 'badass error' i did not mean something you could fix by code. However, AFAIK you can use pcall to capture them. Handling might be complicated and uninformative error messages could be returned.
If you're using Premake and LUA version 5.3.4:
For sake of completeness: You may also just try your luck with path.exists(filename) . I'm not sure which Lua distributions actually have this path namespace (update: Penlight), but at least it is included in Torch:
debug.getinfo(path.exists) tells me that its source is in torch/install/share/lua/5.1/pl/path.lua and it is implemented as follows:
If you are willing to use lfs , you can use lfs.attributes . It will return nil in case of error:
Although it can return nil for other errors other than a non-existing file, if it doesn't return nil , the file certainly exists.
An answer which is windows only checks for files and folders, and also requires no additional packages. It returns true or false .
io.popen(. ):read'*l' - executes a command in the command prompt and reads the result from the CMD stdout
if exist - CMD command to check if an object exists
(echo 1) - prints 1 to stdout of the command prompt
An answer which is windows only checks for files and folders, and also requires no additional packages. It returns true or false.
You can also use the 'paths' package. Here's the link to the package
Not necessarily the most ideal as I do not know your specific purpose for this or if you have a desired implementation in mind, but you can simply open the file to check for its existence.
io.open returns nil if it fails to open the file. As a side note, this is why it is often used with assert to produce a helpful error message if it is unable to open the given file. For instance:
If the file hello.txt does not exist, you should get an error similar to stdin:1: hello.txt: No such file or directory .
For library solution, you can use either paths or path .
paths.filep(path)
Return a boolean indicating whether path refers to an existing file.
paths.dirp(path)
Return a boolean indicating whether path refers to an existing directory.
Although the names are a little bit strange, you can certainly use paths.filep() to check whether a path exists and it is a file. Use paths.dirp() to check whether it exists and it is a directory. Very convenient.
If you prefer path rather than paths , you can use path.exists() with assert() to check the existence of a path, getting its value at the same time. Useful when you are building up path from pieces.
If you just want to check the boolean result, use path.isdir() and path.isfile() . Their purposes are well-understood from their names.
Как я могу проверить, существует ли файл с использованием Lua?
но обратите внимание, что этот код проверяет, может ли файл быть открыт для чтения.
Используя простой Lua, самое лучшее, что вы можете сделать, это посмотреть, можно ли открыть файл для чтения в соответствии с LHF. Это почти всегда достаточно хорошо. Но если вы хотите больше, загрузите Lua POSIX library и проверьте, возвращает ли posix.stat( путь ) не nil .
Я приведу себя из здесь
Я использую эти (но я действительно проверяю на ошибку):
os.rename(name1, name2) переименует имя1 в name2. Используйте одно и то же имя, и ничего не должно измениться (за исключением ошибки badass). Если все работает хорошо, оно возвращает true, иначе оно возвращает nil и errormessage. Если вы не хотите использовать lfs, вы не можете различать файлы и каталоги, не пытаясь открыть файл (который немного медленный, но нормально).
Итак, без LuaFileSystem
Он выглядит короче, но занимает больше времени.
Также открыть файл является рискованным
Получайте удовольствие от кодирования!
Я использую LUA 5.3.4.
Если вы хотите использовать lfs , вы можете использовать lfs.attributes . Он вернет nil в случае ошибки:
Хотя он может возвращать nil для других ошибок, кроме несуществующего файла, если он не возвращает nil , файл, безусловно, существует.
Для полноты: вы также можете просто испытать удачу с помощью path.exists(filename) . Я не уверен, какие дистрибутивы Lua на самом деле имеют это пространство имен path (update: Penlight), но по крайней мере, он включен в факел:
debug.getinfo(path.exists) сообщает мне, что его источник находится в torch/install/share/lua/5.1/pl/path.lua , и он реализован следующим образом:
Ответ, который является только окнами, проверяет файлы и папки, а также не требует дополнительных пакетов. Он возвращает true или false .
io.popen(. ): read '* l' - выполняет команду в командной строке и считывает результат из CMD stdout
если существует - команда CMD для проверки существования объекта
(echo 1) - выводит 1 в стандартный вывод командной строки
Вы также можете использовать пакет "paths". Здесь ссылка на пакет
Для решения библиотеки вы можете использовать либо paths либо path .
paths.filep (путь)
Возвращает логическое значение, указывающее, относится ли путь к существующему файлу.
paths.dirp (путь)
Возвращает логическое значение, указывающее, ссылается ли путь на существующий каталог.
Хотя имена немного странные, вы можете использовать paths.filep() чтобы проверить, существует ли путь и является ли он файлом. Используйте paths.dirp() чтобы проверить, существует ли он и является ли он каталогом. Очень удобно.
Если вы предпочитаете path а не paths , вы можете использовать path.exists() с assert() чтобы проверить существование пути, одновременно получая его значение. Полезно, когда вы строите путь из кусочков.
Если вы просто хотите проверить логический результат, используйте path.isdir() и path.isfile() . Их цели хорошо понятны из их имен.
Как я могу проверить, существует ли файл с помощью Lua?
но обратите внимание, что этот код только проверяет, можно ли открыть файл для чтения.
Лучшее, что вы можете сделать, используя простой Lua, - это посмотреть, можно ли открыть файл для чтения в соответствии с LHF. Этого почти всегда достаточно. Но если вы хотите большего, загрузите библиотеку Lua POSIX и проверьте, не возвращает ли posix.stat( path ) не- nil .
Если вы используете Premake и LUA версии 5.3.4:
Я процитирую себя отсюда
Я использую их (но на самом деле проверяю наличие ошибки):
Итак, без LuaFileSystem
Выглядит короче, но занимает больше времени . Также открывать файл - это рискованно
Как обрабатываются ошибки os.rename, связанные с переименованием файлов, доступных только для чтения?
@carpii Если вы попытаетесь открыть заблокированный файл и прочитать его, это может привести к ошибке (вы все равно хотите знать, является ли это файл или нет). То же самое и с каталогами (если на хосте поддерживается блокировка каталогов).
Для полноты: вы также можете просто попытать счастья с path.exists(filename) . Я не уверен, в каких дистрибутивах Lua на самом деле есть это path пространство имен ( обновление : Penlight ), но, по крайней мере, оно включено в Torch:
debug.getinfo(path.exists) сообщает мне, что его источник находится внутри, torch/install/share/lua/5.1/pl/path.lua и он реализован следующим образом:
Если вы хотите использовать lfs , вы можете использовать lfs.attributes . Он вернется nil в случае ошибки:
Хотя он может возвращаться nil для других ошибок, отличных от несуществующего файла, если он не возвращается nil , файл определенно существует.
Ответ, который заключается в том, что Windows проверяет только файлы и папки, а также не требует дополнительных пакетов. Он возвращает true или false .
io.popen(. ):read'*l' - executes a command in the command prompt and reads the result from the CMD stdout
if exist - CMD command to check if an object exists
(echo 1) - prints 1 to stdout of the command prompt
Ответ, который заключается в том, что Windows проверяет только файлы и папки, а также не требует дополнительных пакетов. Возвращает истину или ложь.
Вы также можете использовать пакет paths. Вот ссылка на пакет
Затем в Lua сделайте:
Не обязательно самый идеальный, поскольку я не знаю вашей конкретной цели для этого или если у вас есть желаемая реализация, но вы можете просто открыть файл, чтобы проверить его существование.
Если файл hello.txt не существует, вы должны получить ошибку, похожую на stdin:1: hello.txt: No such file or directory .
Для библиотечного решения вы можете использовать либо paths или path .
paths.filep(path)
Return a boolean indicating whether path refers to an existing file.
paths.dirp(path)
Return a boolean indicating whether path refers to an existing directory.
Хотя имена немного странные, вы, безусловно, можете использовать их, paths.filep() чтобы проверить, существует ли путь и является ли это файлом. Используйте, paths.dirp() чтобы проверить, существует ли он и является ли это каталогом. Очень удобно.
Если вы предпочитаете , path а не paths , вы можете использовать path.exists() с , assert() чтобы проверить существование пути, получая его значение в то же время. Полезно, когда вы строите путь из кусочков.
Если вы просто хотите проверить логический результат, используйте path.isdir() и path.isfile() . Их цели хорошо понятны из их названий.
Как проверить, существует ли каталог в lua, желательно без использования модуля LuaFileSystem, если это возможно?
попытка сделать что-то вроде этой строки python:
проблема в том, что дистрибутив Lua (почти) включает только функции, указанные в стандарте C. стандарт C не делает никаких предположений о том, что на самом деле существует файловая система любого конкретного вида (или даже операционная система, если на то пошло), поэтому os и io модули не предоставляют информацию о доступе, недоступную из стандартной библиотеки C.
Если бы вы пытались кодировать в чистом стандарте C, у вас было бы то же самое вопрос.
есть шанс, что вы можете узнать, существует ли папка неявно из попытки ее использования. Если вы ожидаете, что он существует и доступен для записи, создайте там временный файл, и если это удастся, папка существует. Если это не удается, вы не сможете отличить несуществующую папку от недостаточных разрешений, конечно.
на сегодняшний день самым легким ответом на получение конкретного ответа будет тонкая привязка только к тем конкретным ОС вызовы функций, которые предоставляют необходимую информацию. Если вы можете принять чужой Луа модуль, тогда вы можете сделать привязку в противном случае чистой Lua.
проще, но немного тяжелее, принять файловую систему Lua. Он предоставляет портативный модуль, который поддерживает большинство вещей, которые можно было бы узнать о файлах и файловой системе.
Это способ, который работает как на Unix, так и на Windows, без каких-либо внешних зависимостей:
Если вы специально заинтересованы в том, чтобы избежать библиотеки LFS,библиотека Lua Posix имеет интерфейс для stat ().
Ну, в справочном руководстве 5.1 ничего нет в ОС таблице, а если вы используете Nixstaller вы получаете os.fileexists именно то, что вы объяснили.
если вы можете позволить себе немного повозиться, или если вы знаете, на какой ОС вы будете работать, вам может сойти с рук стандартная библиотека ОС os.execute с некоторым системным вызовом, который определит, существует ли файл.
даже лучше, чем ОС.выполнение может быть ОС.переименовать:
os.rename(oldname, newname)
переименовывает по имени oldname to newname . Если эта функция не работает, она возвращает nil, плюс строка, описывающая ошибка.
вы можете попробовать установить oldname и newname то же самое-у вас может не быть прав на запись, поэтому он может потерпеть неудачу, потому что вы не можете писать, хотя вы can читать. В этом случае вам придется проанализировать возвращенную строку ошибки и вывести, есть ли у вас можно написать, или вам нужно просто попробовать выполнить свою функцию, которая нуждается в существующем файле, и обернуть ее в pcall .
Moving Around In Files
Lua offers a seek function. Seek works the same in 5.1, 5.2, and 5.3.
This has the following starting points:
set | Set to start from the beginning of the file. |
---|---|
cur | Move from the current position the file is at. |
end | Move from the end of the file. |
Since we start at the beginning of the file, we’d get the following with cur:
Let’s test a few other methods:
[file]:seek() gets you the current position for later usage.
Making It Cleaner
We’re going to get into Lua Idioms with the assert function. This function basically makes Lua check whether the condition is going to succeed or not and gracefully fail with an error.
Let’s see it in action:
We’ve now cleanly errored out of the program without trying to read a file which does not exist.
Let’s learn about io.type( [filehandle] ). This is extremely useful for checking on if a file is able to get a file handle. io.type( [filehandle] ) returns either “file” (the handle is valid), “closed file” (the handle is closed), or nil (it failed). Here’s an example:
Now, instead of just exiting out, we have error handling. This is far cleaner than just using assert and exiting out. The assert function still has its place for debugging, but now we’ve made our program fault resilient and graceful as long as we handle it correctly.
Yoni, I understand you just joined SO. Welcome. Few things to mention. 1) Don't answer your own question with a new question. 2) Try to search around (Google is your friend) for more info and only if you are completely stuck ask here. This I believe will make you a better developer.
More File Operations
[file]:flush() syncs the data to disk for the file.
The Lua Manual has a lot more than we can include here. See these for a reference to some of the functions as written in 5.3.
Open and Close
Before we get into either reading or writing, we need to discuss opening and closing files. Your workflow will typically involve opening a file, doing whatever with it, then explicitly closing it. When you exit the program, the file should close as well, but that’s considered poor practice.
The filename is where the file is, and the mode is listed in the table below (or following the same mode as in C for fopen). If there is no mode, r is implied.
r | (Default) Open the file read only. |
---|---|
w | Open the file to write. Overwrites contents or makes a new file. |
a | Append the file. Write to the end or make a new file. Repositioning operations are ignored. |
r+ | Open the file in read and write mode. The file must exist. |
w+ | Open the file to write. Clears existing contents or makes a new file. |
a+ | Append the file with read mode. Write to the end or make a new file. Repositioning operations affect read mode. |
You can also use the b modifier at the end of the mode in order to open the file in binary mode. For example:
io.open returns a file handle object. When working with opening files, you should assign the file handle to a variable to do anything useful.
Once you’re done with a file, you need to close it.
Reading Files
Once you open your file, you can read it. Reading is done via:
The options correspond to the following table for Lua 5.1 and 5.2:
*line | *l | Reads a single line from the file. |
---|---|---|
*all | *a | Reads all of the content from the file. |
*number | *n | Reads a number from the file. This reads until the end of a valid sequence. |
[number] | (integer) | Reads [number] characters (bytes) from the file. Does not use quotes. |
Lua 5.3 is adds the following (but is backwards compatible):
a | Reads all of the content from the file. |
---|---|
l | Reads a single line from the file. |
L | Reads a single line from the file, but keeps the end of line character(s) |
n | Reads a number from the file. This reads until the end of a valid sequence. |
[number] | Reads [number] characters (bytes) from the file. Does not use quotes. |
These basically all return nil if there isn’t a valid sequence, except for the “all” options which return an empty string as long as the file is valid.
Let’s see it all in action with test.txt:
(Note the new line at the end of test.txt)
Let’s try each of our options out for reading and see what we get. We’re going to start the whole file over and over again to avoid any issues.
Let’s do the same with Lua 5.3:
Open and Close
Before we get into either reading or writing, we need to discuss opening and closing files. Your workflow will typically involve opening a file, doing whatever with it, then explicitly closing it. When you exit the program, the file should close as well, but that’s considered poor practice.
The filename is where the file is, and the mode is listed in the table below (or following the same mode as in C for fopen). If there is no mode, r is implied.
r | (Default) Open the file read only. |
---|---|
w | Open the file to write. Overwrites contents or makes a new file. |
a | Append the file. Write to the end or make a new file. Repositioning operations are ignored. |
r+ | Open the file in read and write mode. The file must exist. |
w+ | Open the file to write. Clears existing contents or makes a new file. |
a+ | Append the file with read mode. Write to the end or make a new file. Repositioning operations affect read mode. |
You can also use the b modifier at the end of the mode in order to open the file in binary mode. For example:
io.open returns a file handle object. When working with opening files, you should assign the file handle to a variable to do anything useful.
Once you’re done with a file, you need to close it.
Writing Files
Luckily, in Lua, writing is way easier than reading. You just use [file]:write( [contents] ) to write to the given file.
(Note: the extra end line)
What happens if you don’t use /n (the newline control character)?
Читайте также: