Add file.stat() to query file/directory attributes. (#1724)
* add file.stat() * set default time/date to 1970-01-01 use lua_setfield
This commit is contained in:
parent
07031f569a
commit
305d7c4672
|
@ -13,6 +13,14 @@
|
||||||
|
|
||||||
#define FILE_READ_CHUNK 1024
|
#define FILE_READ_CHUNK 1024
|
||||||
|
|
||||||
|
// use this time/date in absence of a timestamp
|
||||||
|
#define FILE_TIMEDEF_YEAR 1970
|
||||||
|
#define FILE_TIMEDEF_MON 01
|
||||||
|
#define FILE_TIMEDEF_DAY 01
|
||||||
|
#define FILE_TIMEDEF_HOUR 00
|
||||||
|
#define FILE_TIMEDEF_MIN 00
|
||||||
|
#define FILE_TIMEDEF_SEC 00
|
||||||
|
|
||||||
static int file_fd = 0;
|
static int file_fd = 0;
|
||||||
static int file_fd_ref = LUA_NOREF;
|
static int file_fd_ref = LUA_NOREF;
|
||||||
static int rtc_cb_ref = LUA_NOREF;
|
static int rtc_cb_ref = LUA_NOREF;
|
||||||
|
@ -33,12 +41,12 @@ static void table2tm( lua_State *L, vfs_time *tm )
|
||||||
lua_getfield( L, idx, "min" );
|
lua_getfield( L, idx, "min" );
|
||||||
lua_getfield( L, idx, "sec" );
|
lua_getfield( L, idx, "sec" );
|
||||||
|
|
||||||
tm->year = luaL_optint( L, ++idx, 2016 );
|
tm->year = luaL_optint( L, ++idx, FILE_TIMEDEF_YEAR );
|
||||||
tm->mon = luaL_optint( L, ++idx, 6 );
|
tm->mon = luaL_optint( L, ++idx, FILE_TIMEDEF_MON );
|
||||||
tm->day = luaL_optint( L, ++idx, 21 );
|
tm->day = luaL_optint( L, ++idx, FILE_TIMEDEF_DAY );
|
||||||
tm->hour = luaL_optint( L, ++idx, 0 );
|
tm->hour = luaL_optint( L, ++idx, FILE_TIMEDEF_HOUR );
|
||||||
tm->min = luaL_optint( L, ++idx, 0 );
|
tm->min = luaL_optint( L, ++idx, FILE_TIMEDEF_MIN );
|
||||||
tm->sec = luaL_optint( L, ++idx, 0 );
|
tm->sec = luaL_optint( L, ++idx, FILE_TIMEDEF_SEC );
|
||||||
|
|
||||||
// remove items from stack
|
// remove items from stack
|
||||||
lua_pop( L, 6 );
|
lua_pop( L, 6 );
|
||||||
|
@ -317,6 +325,72 @@ static int file_rename( lua_State* L )
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lua: stat(filename)
|
||||||
|
static int file_stat( lua_State* L )
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
const char *fname = luaL_checklstring( L, 1, &len );
|
||||||
|
luaL_argcheck( L, c_strlen(fname) <= FS_OBJ_NAME_LEN && c_strlen(fname) == len, 1, "filename invalid" );
|
||||||
|
|
||||||
|
vfs_item *stat = vfs_stat( (char *)fname );
|
||||||
|
|
||||||
|
if (!stat) {
|
||||||
|
lua_pushnil( L );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_createtable( L, 0, 7 );
|
||||||
|
|
||||||
|
lua_pushinteger( L, vfs_item_size( stat ) );
|
||||||
|
lua_setfield( L, -2, "size" );
|
||||||
|
|
||||||
|
lua_pushstring( L, vfs_item_name( stat ) );
|
||||||
|
lua_setfield( L, -2, "name" );
|
||||||
|
|
||||||
|
lua_pushboolean( L, vfs_item_is_dir( stat ) );
|
||||||
|
lua_setfield( L, -2, "is_dir" );
|
||||||
|
|
||||||
|
lua_pushboolean( L, vfs_item_is_rdonly( stat ) );
|
||||||
|
lua_setfield( L, -2, "is_rdonly" );
|
||||||
|
|
||||||
|
lua_pushboolean( L, vfs_item_is_hidden( stat ) );
|
||||||
|
lua_setfield( L, -2, "is_hidden" );
|
||||||
|
|
||||||
|
lua_pushboolean( L, vfs_item_is_sys( stat ) );
|
||||||
|
lua_setfield( L, -2, "is_sys" );
|
||||||
|
|
||||||
|
lua_pushboolean( L, vfs_item_is_arch( stat ) );
|
||||||
|
lua_setfield( L, -2, "is_arch" );
|
||||||
|
|
||||||
|
// time stamp as sub-table
|
||||||
|
vfs_time tm;
|
||||||
|
int got_time = VFS_RES_OK == vfs_item_time( stat, &tm ) ? TRUE : FALSE;
|
||||||
|
|
||||||
|
lua_createtable( L, 0, 6 );
|
||||||
|
|
||||||
|
lua_pushinteger( L, got_time ? tm.year : FILE_TIMEDEF_YEAR );
|
||||||
|
lua_setfield( L, -2, "year" );
|
||||||
|
|
||||||
|
lua_pushinteger( L, got_time ? tm.mon : FILE_TIMEDEF_MON );
|
||||||
|
lua_setfield( L, -2, "mon" );
|
||||||
|
|
||||||
|
lua_pushinteger( L, got_time ? tm.day : FILE_TIMEDEF_DAY );
|
||||||
|
lua_setfield( L, -2, "day" );
|
||||||
|
|
||||||
|
lua_pushinteger( L, got_time ? tm.hour : FILE_TIMEDEF_HOUR );
|
||||||
|
lua_setfield( L, -2, "hour" );
|
||||||
|
|
||||||
|
lua_pushinteger( L, got_time ? tm.min : FILE_TIMEDEF_MIN );
|
||||||
|
lua_setfield( L, -2, "min" );
|
||||||
|
|
||||||
|
lua_pushinteger( L, got_time ? tm.sec : FILE_TIMEDEF_SEC );
|
||||||
|
lua_setfield( L, -2, "sec" );
|
||||||
|
|
||||||
|
lua_setfield( L, -2, "time" );
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// g_read()
|
// g_read()
|
||||||
static int file_g_read( lua_State* L, int n, int16_t end_char, int fd )
|
static int file_g_read( lua_State* L, int n, int16_t end_char, int fd )
|
||||||
{
|
{
|
||||||
|
@ -561,6 +635,7 @@ static const LUA_REG_TYPE file_map[] = {
|
||||||
{ LSTRKEY( "exists" ), LFUNCVAL( file_exists ) },
|
{ LSTRKEY( "exists" ), LFUNCVAL( file_exists ) },
|
||||||
{ LSTRKEY( "fsinfo" ), LFUNCVAL( file_fsinfo ) },
|
{ LSTRKEY( "fsinfo" ), LFUNCVAL( file_fsinfo ) },
|
||||||
{ LSTRKEY( "on" ), LFUNCVAL( file_on ) },
|
{ LSTRKEY( "on" ), LFUNCVAL( file_on ) },
|
||||||
|
{ LSTRKEY( "stat" ), LFUNCVAL( file_stat ) },
|
||||||
#ifdef BUILD_FATFS
|
#ifdef BUILD_FATFS
|
||||||
{ LSTRKEY( "mount" ), LFUNCVAL( file_mount ) },
|
{ LSTRKEY( "mount" ), LFUNCVAL( file_mount ) },
|
||||||
{ LSTRKEY( "chdir" ), LFUNCVAL( file_chdir ) },
|
{ LSTRKEY( "chdir" ), LFUNCVAL( file_chdir ) },
|
||||||
|
|
|
@ -294,6 +294,55 @@ Renames a file. If a file is currently open, it will be closed first.
|
||||||
file.rename("temp.lua","init.lua")
|
file.rename("temp.lua","init.lua")
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## file.stat()
|
||||||
|
|
||||||
|
Get attribtues of a file or directory in a table:
|
||||||
|
|
||||||
|
- `size` file size in bytes
|
||||||
|
- `name` file name
|
||||||
|
- `time` table with time stamp information. Default is 1970-01-01 00:00:00 in case time stamps are not supported (on SPIFFS).
|
||||||
|
- `year`
|
||||||
|
- `mon`
|
||||||
|
- `day`
|
||||||
|
- `hour`
|
||||||
|
- `min`
|
||||||
|
- `sec`
|
||||||
|
- `is_dir` flag `true` if item is a directory, otherwise `false`
|
||||||
|
- `is_rdonly` flag `true` if item is read-only, otherwise `false`
|
||||||
|
- `is_hidden` flag `true` if item is hidden, otherwise `false`
|
||||||
|
- `is_sys` flag `true` if item is system, otherwise `false`
|
||||||
|
- `is_arch` flag `true` if item is archive, otherwise `false`
|
||||||
|
|
||||||
|
#### Syntax
|
||||||
|
`file.stat(filename)`
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
`filename` file name
|
||||||
|
|
||||||
|
#### Returns
|
||||||
|
table containing file attributes
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
```lua
|
||||||
|
s = file.stat("/SD0/myfile")
|
||||||
|
print("name: " .. s.name)
|
||||||
|
print("size: " .. s.size)
|
||||||
|
|
||||||
|
t = s.time
|
||||||
|
print(string.format("%02d:%02d:%02d", t.hour, t.min, t.sec))
|
||||||
|
print(string.format("%04d-%02d-%02d", t.year, t.mon, t.day))
|
||||||
|
|
||||||
|
if s.is_dir then print("is directory") else print("is file") end
|
||||||
|
if s.is_rdonly then print("is read-only") else print("is writable") end
|
||||||
|
if s.is_hidden then print("is hidden") else print("is not hidden") end
|
||||||
|
if s.is_sys then print("is system") else print("is not system") end
|
||||||
|
if s.is_arch then print("is archive") else print("is not archive") end
|
||||||
|
|
||||||
|
s = nil
|
||||||
|
t = nil
|
||||||
|
```
|
||||||
|
|
||||||
# File access functions
|
# File access functions
|
||||||
|
|
||||||
The `file` module provides several functions to access the content of a file after it has been opened with [`file.open()`](#fileopen). They can be used as part of a basic model or an object model:
|
The `file` module provides several functions to access the content of a file after it has been opened with [`file.open()`](#fileopen). They can be used as part of a basic model or an object model:
|
||||||
|
|
Loading…
Reference in New Issue