Свойства файла
Получение свойств файла
Для кроссплатформенного получения свойств файла в библиотеке libuv есть три функции
int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
Первая функция uv_fs_stat, возвращает статистику по файлу (статус файла). Отличие uv_fs_lstat в том, что если указанный файл является ссылкой, то будет возвращена статистика непосредственно по файлу-ссылке, а не по файлу, на который ссылка ссылается. Функция uv_fs_fstat получает в качестве аргумента не строку – имя файла, - а уже открытый файл типа uv_file – кроссплатформенная реализация дескриптора файлов. Статистика будет в поле statbuf запроса в колбэке. Поле statbuf имеет тип uv_stat_t, поля которого несут информацию о файле
typedef struct { uint64_t st_dev; uint64_t st_mode; uint64_t st_nlink; uint64_t st_uid; uint64_t st_gid; uint64_t st_rdev; uint64_t st_ino; uint64_t st_size; uint64_t st_blksize; uint64_t st_blocks; uint64_t st_flags; uint64_t st_gen; uv_timespec_t st_atim; uv_timespec_t st_mtim; uv_timespec_t st_ctim; uv_timespec_t st_birthtim; } uv_stat_t;
- st_dev - идентификатор устройства, которое владеет файлом.
- st_mode – тип файла
- st_nlink – число жёстких ссылок на файл. Если жёстких ссылок нет, то число равно 1 (сам файл)
- st_uid, st_gid – идентификатор пользователя и группы
- st_rdev – идентификатор устройства (если это специальный файл)
- st_ino – inode файла
- st_size – размер файла
- st_blksize – размер блока
- st_blocks – число выделенных блоков под файл
- st_flags – специальные флаги (user defined flags)
- st_gen – номер поколения файла
- st_atime – время последнего обращения к файлу
- st_mtime – время последней модификации (открытие для записи или дозаписи в конец)
- st_ctime – время последнего изменения прав на файл (например, chmod)
- st_birthtime – время создания
Получение статистики довольно простая задача. Единственная проблема – перевод времени в печатный формат. В коде программы указано, как это сделать.
#include <uv.h> #include <stdio.h> #include <fcntl.h> #include <sys/stat.h> #ifdef _WIN32 #include <conio.h> #define wait() _getch() #define S_IFBLK 0 #define S_IFSOCK 0 #define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFMT) #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) #define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) #define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) #define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK) #define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) #define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK) #else #define wait() scanf("1"); #endif uv_loop_t* loop; uv_fs_t stat_req; void stat_cb(uv_fs_t*); const char *filename = "C:/c/somefile.txt"; int main(int argc, char **argv) { int r; loop = uv_default_loop(); uv_fs_stat(loop, &stat_req, filename, stat_cb); uv_run(loop, UV_RUN_DEFAULT); return 0; } void stat_cb(uv_fs_t* req) { uv_stat_t stat; struct tm * timeinfo; char buff[20]; stat = req->statbuf; //number of hard links to file printf("st_nlink %d\n", stat.st_nlink); //blocksize printf("st_blksize %d\n", stat.st_blksize); //number of blocks allocated printf("st_blocks %d\n", stat.st_blocks); //st_atime - time of last access timeinfo = localtime(&stat.st_atim); strftime(buff, 20, "%b %d %H:%M", timeinfo); printf("st_atime: %s\n", buff); //st_mtime - time of last modification timeinfo = localtime(&stat.st_mtim); strftime(buff, 20, "%b %d %H:%M", timeinfo); printf("st_mtime: %s\n", buff); //st_ctime - time of last status change timeinfo = localtime(&stat.st_ctim); strftime(buff, 20, "%b %d %H:%M", timeinfo); printf("st_ctime: %s\n", buff); wait(); }
Небольшое дополнение. В самом начале программы идёт набор макросов. Это кроссплатформенная реализация стандартных POSIX макросов для определения типа файлов. Эту информация можно получить с использованием функций чтения содержимого папки (см. предыдущий раздел). Для работы программы эти макросы не нужны.
