Linux系统编程 1、文件IO、文件属性、文件目录操作函数
1. 文件IO函数
1.1 open:打开文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
参数:
- pathname: 要操作的文件的文件名
- flags: 对文件的操作权限
必选项: O_RDONLY, O_WRONLY, or O_RDWR, 不能同时用, 只能用一个
可选项:
- O_APPEND: 追加, 指定文件文件有写权限的时候可追加
- O_CREAT: 文件存在不创建, 不存在就创建
- O_EXCL: 检测文件是否存在, 必须要和O_CREAT一起使用
O_CREAT | O_EXCL
- mode: 8进制整形数, 0777, 创建出的新文件的权限
- 实际权限的算法: (mode & ~umask)
- 假设: 权限: 0664, umask: 0002, ~umask: 775
110110100
111111101
&
110110100
返回值:
- 成功: 可用文件描述符
- 失败: -1
1.2 close:关闭文件
#include <unistd.h>
int close(int fd);
参数:
fd: open执行成功得到的文件描述符
int fd2 = open("./world.txt", O_RDWR|O_CREAT|O_EXCL, 0777);
printf("fd2 = %d\n", fd2);
if(fd2 == -1)
{
perror("open-world.txt");
}
1.3 read:读文件
#include <stdio.h>
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
参数:
- fd: open文件之后得到的文件描述符, 通过该fd可用找到磁盘文件
- buf: 存储数据的缓冲区地址(数组地址)
- count: 缓冲区大小(数组最大容量)
返回值:
- 成功: 读到的字节数
- 文件读完了: 返回0
- 失败: -1
1.4 write:读文件
#include <stdio.h>
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
参数:
- fd: open文件之后得到的文件描述符, 通过该fd可用找到磁盘文件
- buf: 存储了要写的数据
- count: buf中存储的有效数据的长度
返回值:
- 成功: 写入的字节数
- 什么也没写: 0
- 失败: -1
1.5 lseek:文件指针偏移
#include <stdio.h>
int fseek(FILE *stream, long offset, int whence);
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
参数:
- fd: open文件之后得到的文件描述符, 通过该fd可用找到磁盘文件
- offset: 一个整形的偏移量
- whence:
SEEK_SET: 设置文件指针偏移量, 偏移量就是通过第二个参数指定的
SEEK_CUR: 当前文件指针偏移量 + 第二个参数指定的偏移
SEEK_END: 当前文件大小 + 第二个参数指定的偏移
返回值: 文件指针最后的偏移值
lseek(fd, 0, SEEK_SET);
lseek(fd, 0, SEEK_CUR);
lseek(fd, 0, SEEK_END);
lseek(fd, 10, SEEK_END);
write(fd, " ", 1);
1.6 perror:查看错误号
查看错误号:
/usr/include/asm-generic/errno-base.h
/usr/include/asm-generic/errno.h
errno: Linux系统函数库中的全局变量, 记录函数调用失败之后的错误号, 每个错误号都有对应的错误描述
#include <stdio.h>
void perror(const char *s);
2. 文件属性函数
2.1 access( ):判断文件权限, 或者文件是否存在
int access(const char *pathname, int mode);
参数:
- pathname: 文件名
- mode:
R_OK: 判断文件是不是有读权限
W_OK: 判断文件是不是有写权限
X_OK: 判断文件是不是有执行权限
F_OK: 判断当前文件是否存在
返回值:
判断成功: 0, 失败: -1
文件有判断的权限:0
文件没有判断的权限:-1
2.2 chmod( ):修改文件权限
int chmod(const char *filename, int mode);
参数:
- filename: 要修改文件权限的文件的名字
- mod: 八进制数
2.3 chown( ):修改文件所有者
int chown(const char *path, uid_t owner, gid_t group);
参数:
- path: 要修改的文件的名字
- owner: 用户ID, stat /etc/passwd
- group: 组ID /etc/group
2.4 truncate( ):修改文件大小
int truncate(const char *path, off_t length);
参数:
- path: 要操作的文件
- length: 最终的文件大小
- length > 源文件大小 ==> 文件拓展, 添加字符0
- length < 源文件大小 ==> 文件被裁剪, 尾部的被删除
3. 文件目录操作函数
3.1 rename( ):文件重命名
int rename(const char *oldpath, const char *newpath);
参数:
- oldpath: 旧的文件名
- newpath: 新的文件名
3.2 chdir( ):修改进程的工作目录
int chdir(const char *path);
3.3 getcwd( ) == pwd命令
char *getcwd(char *buf, size_t size);
参数:
- buf: 存储路径, 指向一个由内存大小为size的数组
- size: 修饰buf大小
返回值:
指针指向一块内存, 这个内存就是第一个参数
3.4 mkdir( ):创建目录
int mkdir(const char *pathname, mode_t mode);
参数:
- pathname: 目录名
- mode: 目录的权限 mode & ~umask
3.5 rmdir( ) == rmdir命令, 只能删除空目录 rm -r
int rmdir(const char *pathname);
3.6 unlink( ):删除磁盘文件 自动清除缓存
#include <unistd.h>
int unlink(const char *pathname);
int fd = open("hello.txt", o_rdwr);
unlink("hello.txt");
......;
.......;
close(fd);
3.7 opendir:打开目录、readdir:读目录
struct dirent
{
ino_t d_ino;
ff_t d_off;
signed short int d_reclen;
unsigned char d_type;
har d_name[256];
};
d_type
DT_BLK - 块设备
DT_CHR - 字符设备
DT_DIR - 目录
DT_LNK - 软连接
DT_FIFO - 管道
DT_REG - 普通文件
DT_SOCK - 套接字
DT_UNKNOWN - 未知
DIR *opendir(const char *name);
参数:
name: 要打开的目录
返回值:
成功: 有效指针, 失败: NULL
struct dirent *readdir(DIR *dirp);
参数:
opendir的返回值
返回值:
一个结构体, 这个对应一个文件
读某个目录下普通文件的个数
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <dirent.h>
int getFileNums(const char* path)
{
DIR* dir = opendir(path);
if(dir == NULL)
{
perror("opendir");
return 0;
}
int count = 0;
struct dirent *ptr;
while( (ptr = readdir(dir)) != NULL)
{
if(strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0)
{
continue;
}
else if(ptr->d_type == DT_DIR)
{
char subPath[1024];
sprintf(subPath, "%s/%s", path, ptr->d_name);
count += getFileNums(subPath);
}
else if(ptr->d_type == DT_REG)
{
count ++;
}
}
closedir(dir);
return count;
}
int main(int argc, char* argv[])
{
int count = getFileNums(argv[1]);
printf("普通文件个数: %d\n", count);
return 0;
}