作者: Andy. 时间: 2016-08-13 11:33:14
介绍一下Linux下C语言的文件管理。很简单,很基础的。
文件的打开操作有系统调用和标准库的调用两种,用man命令可以很清楚看到他们的用法和区别。说一下有意思的地方吧,比如fread,看看man的描述:
NAME fread, fwrite - binary stream input/output SYNOPSIS #include <stdio.h> size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); DESCRIPTION The function fread() reads nmemb elements of data, each size bytes long, from the stream pointed to by stream, storing them at the loca‐ tion given by ptr. The function fwrite() writes nmemb elements of data, each size bytes long, to the stream pointed to by stream, obtaining them from the location given by ptr. For nonlocking counterparts, see unlocked_stdio(3).
实际的读取大小为size*nmemb的量,返回的事读到的nmemb的数量。比如size = 10,nmemb = 20,但是只读到了199的数据,小于size*nmemb的200,那么返回值为19,而不是20。感觉上面的描述对这点儿的描述不是那么的清楚。蛮有意思的。
开一个简单的写日志的代码,读取时间什么的,写文件。直接看函数吧,都是一些函数的调用,没什么其他的:
void Write_Log(const char * message){ time_t now_date; struct tm * now_time; char filename[20]; char s_message[1024]; time(&now_date); now_time = localtime(&now_date); char s_time[20]; sprintf(s_time, "%4d-%d-%d %d:%d:%d", now_time->tm_year + 1900, now_time->tm_mon + 1, now_time->tm_mday, now_time->tm_hour, now_time->tm_min, now_time->tm_sec); sprintf(s_message, "%s %s\n", s_time, message); sprintf(filename, "%d%d%d.log", now_time->tm_year + 1900, now_time->tm_mon + 1, now_time->tm_mday); FILE * file = fopen(filename, "a+"); if ( file == NULL ) { perror("Open log file error."); return; } fputs(s_message, file); fclose(file); }
对用户输入的路径进行判断,是文件还是目录。列出目录的文件等等。都是很简单的函数调用,看代码吧:
int main(int argc, char * argv[]){ if(argc < 2){ Write_Log("Path is error."); return -1; } struct stat file_stat; if(stat(argv[1], &file_stat) == -1){ Write_Log(strerror(errno)); return -1; } if(S_ISREG(file_stat.st_mode)){ char string[1024]; memset(string, 0, sizeof(string)); FILE * file = fopen(argv[1], "r"); fread(string, 1, 1023, file); printf("%s\n", string); } if(S_ISDIR(file_stat.st_mode)){ DIR * dir; struct dirent * dirent_pointer; dir = opendir(argv[1]); if(dir == NULL){ Write_Log(strerror(errno)); return -1; } while((dirent_pointer = readdir(dir)) != NULL){ printf("%c %s\n", dirent_pointer->d_type, dirent_pointer->d_name); } } Write_Log("Complete"); }
通过man可以看到stat函数的用法:
同时,里面也有stat这个结果的结构:
struct stat { dev_t st_dev; /* ID of device containing file */ ino_t st_ino; /* inode number */ mode_t st_mode; /* protection */ nlink_t st_nlink; /* number of hard links */ uid_t st_uid; /* user ID of owner */ gid_t st_gid; /* group ID of owner */ dev_t st_rdev; /* device ID (if special file) */ off_t st_size; /* total size, in bytes */ blksize_t st_blksize; /* blocksize for filesystem I/O */ blkcnt_t st_blocks; /* number of 512B blocks allocated */ /* Since Linux 2.6, the kernel supports nanosecond precision for the following timestamp fields. For the details before Linux 2.6, see NOTES. */ struct timespec st_atim; /* time of last access */ struct timespec st_mtim; /* time of last modification */ struct timespec st_ctim; /* time of last status change */ #define st_atime st_atim.tv_sec /* Backward compatibility */ #define st_mtime st_mtim.tv_sec #define st_ctime st_ctim.tv_sec };
每个成员的意思,通过相应的成员我们可以得到文件大小等等信息。同时,通过相应的宏调用可以判断文件的类型:
这些都是给得蛮清楚的。
运行一下上面的代码,结果如下:
[[email protected] filem]# make gcc -o a.out 1.o [[email protected] filem]# ./a.out 1.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> [[email protected] filem]# ./a.out ../filem/ . test.c .. 1.o 2016812.log makefile 2016813.log 1.c text.txt a.out
如果想获取系统的相关信息,其实可以直接读取/proc下面的文件喔~~
[[email protected] proc]# cat cpuinfo processor : 0 vendor_id : AuthenticAMD cpu family : 21 model : 16 model name : AMD A