Свойства файла

Теги: stat си, fstat си, lstat си, статус файла, свойства файла, получить время создания



Получение свойств файла

Для кроссплатформенного получения свойств файла в библиотеке 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 макросов для определения типа файлов. Эту информация можно получить с использованием функций чтения содержимого папки (см. предыдущий раздел). Для работы программы эти макросы не нужны.

Q&A

Всё ещё не понятно? – пиши вопросы на ящик email
Работа с папками