Linux C 文件编程
系统调用比标准库移植性差(不同OS接口不一定一致)
系统调用会进入内核态, 对程序运行的开销较大.
默认文件描述符 0:标准输入 1:标准输出 2:标准错误输出
文件常用API
- open 打开文件, 返回文件描述符.
- close 关闭文件
- read 读取文件, 返回读取的字节.
- write 写入文件, 返回写入的字节.
- access 判断 文件/目录 是否存在及访问权限
- fcntl 对文件描述符提供控制, 从而改变文件属性.
- lseek 定位文件读写位置, 返回与原位置的差值.
- dup 复制文件描述符, 返回新的文件描述符.
- stat函数族 获取文件的元数据(状态)
- stat 通过文件路径来获取文件元数据
- fstat 通过文件描述符来获取文件元数据
- lstat 获取软链接文件本身的元数据, 其他同stat.
目录常用API
- getcwd 获取当前工作目录
- chdir 改变当前目前工作目录到指定目录
- chroot 改变根目录到指定目录
- mkdir 创建目录
- rmdir 删除目录(必须为空目录)
- opendir 打开目录, 返回DIR*指针.
- closedir 关闭目录
- readdir 获取目录信息, 返回dirent*结构体.
其他常用API
- umask 改变 文件/目录 默认权限掩码
- chmod 改变 文件/目录 权限
- chown 改变 文件/目录 属主和属组
- link函数族 链接文件
- link 硬链接文件
- symlink 软链接文件
- unlink 删除文件一次硬链接(删除文件)
文件复制
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <stdlib.h>
#include <errno.h>
#define MAXLINE 80
void if_error(int stat_code, char *err_msg)
{
if (stat_code < 0) {
perror(err_msg);
exit(errno);
}
}
int main(int argc, char **argv)
{
char *src, *dest;
int fd_rd, fd_wr;
int n_rd, n_wr;
char buf[MAXLINE];
if (argc != 3) return -1;
/* set src, dest file by argv */
src = argv[1];
dest = argv[2];
fd_rd = open(src, O_RDONLY);
if_error(fd_rd, "open");
fd_wr = open(dest, O_WRONLY|O_CREAT, 0664);
if_error(fd_wr, "open");
while (1) {
n_rd = read(fd_rd, buf, MAXLINE);
if_error(n_rd, "read");
if (n_rd == 0) break;
n_wr = write(fd_wr, buf, n_rd);
if_error(n_wr, "write");
}
close(fd_rd);
close(fd_wr);
return 0;
}
获取文件元数据
access time: 访问文件内容时间
change time: 修改文件属性时间
modify time: 修改文件内容时间
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
void if_error(int stat_code, char *err_msg)
{
if (stat_code < 0) {
perror(err_msg);
exit(errno);
}
}
void get_type(char *path)
{
int ret;
struct stat info;
mode_t mode;
ret = lstat(path, &info);
if_error(ret, "stat");
mode = info.st_mode;
if (S_ISREG(mode)) printf("type: file\n");
else if (S_ISDIR(mode)) printf("type: dir\n");
else if (S_ISLNK(mode)) printf("type: symbol link file\n");
else if (S_ISCHR(mode)) printf("type: character device file\n");
else if (S_ISBLK(mode)) printf("type: block device file\n");
else if (S_ISFIFO(mode)) printf("type: fifo file\n");
else if (S_ISSOCK(mode)) printf("type: socket file\n");
}
void get_perm(char *path)
{
int ret;
struct stat info;
mode_t mode;
ret = lstat(path, &info);
if_error(ret, "stat");
mode = info.st_mode;
if (mode & S_IRUSR) printf("owner can read\n");
if (mode & S_IWUSR) printf("owner can write\n");
if (mode & S_IRGRP) printf("group can read\n");
if (mode & S_IWGRP) printf("group can write\n");
if (mode & S_IROTH) printf("others can read\n");
if (mode & S_IWOTH) printf("others can write\n");
}
void get_time(char *path)
{
int ret;
struct stat info;
ret = lstat(path, &info);
if_error(ret, "stat");
printf("access time: %s", ctime(&info.st_atime));
printf("modify time: %s", ctime(&info.st_mtime));
printf("change time: %s", ctime(&info.st_ctime));
}
int main(int argc, char **argv)
{
char *path;
if (argc != 2) return -1;
path = argv[1];
get_type(path);
get_perm(path);
get_time(path);
return 0;
}
遍历目录下文件
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#define MAXLINE 80
void if_error(int stat_code, char *err_msg)
{
if (stat_code < 0) {
perror(err_msg);
exit(errno);
}
}
void list_file(char *path)
{
DIR *dir;
struct dirent *entry;
struct stat info;
char buf[MAXLINE];
int ret;
dir = opendir(path);
if (NULL == dir) exit(-1);
while(1) {
/* search file one by one */
entry = readdir(dir);
if (NULL == entry) break;
/* ignone . and .. */
if(!strncmp(entry->d_name, ".", 1) || !strncmp(entry->d_name, "..", 2))
continue;
sprintf(buf ,"%s/%s", path, entry->d_name);
/* get file info */
ret = lstat(buf, &info);
if_error(ret, "lstat");
/* recur if it is dir else print file name */
if (S_ISDIR(info.st_mode)) {
list_file(buf);
} else {
printf("%s\n", buf);
}
}
closedir(dir);
}
int main(int argc, char **argv)
{
char *path;
if (argc != 2) return -1;
path = argv[1];
list_file(path);
return 0;
}