命令
创建文件: touch 文件名
查看帮助: man 1 名称 Shell命令
man 2 名称 LINUX库
man 3 名称 标准C库
标准C库函数 和 Linux系统函数
标准c库函数调用系统底层API;
标准c库函数有缓冲区,效率高
虚拟地址空间
文件描述符
Linux系统IO函数:
Linux open()
1.打开已经存在的文件
2.创建新文件
Linux read() write()
Linux lseek()
Linux stat() lstat()
说明:
查看文件信息:stat a.txt
八进制数以0开头,十六进制数以0x开头
套接字:八进制 1 4 0 0 0 0
二进制 001 |100|000|000|000|000
创建软链接:
示例:
模拟ls-l命令
//模拟实现 ls-l 指令 // chen@VM-chen:~/Linux/lesson12$ ls -l a.txt // -rw-rw-r-- 1 chen chen 18 7月 13 16:51 a.txt #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #include <pwd.h> #include <grp.h> #include <time.h> #include <string.h> //argc 参数个数 //argv[] C风格字符串数组 //argv: ./ls a.txt , argc自动填充 int main(int argc,char * argv[]){ //判断输入参数是否正确 if(argc < 2){ printf("%s filename\n",argv[0]); return -1; } //获取文件信息 struct stat st; int ret = stat(argv[1],&st); if(ret == -1){ perror("stat"); return -1; } //获取文件类型和权限 char perms[11] = {0}; //用于保存文件类型和权限的字符数组 文件类型:1位 文件权限:3*3位 //========================================判断文件类型====================================== //========================st_mode 与 掩码(__S_IFMT) 进行与操作============================= switch(st.st_mode & __S_IFMT){ case S_IFLNK: perms[0] = 'l'; break; case S_IFDIR: perms[0] = 'd'; break; case S_IFREG: perms[0] = '-'; break; case S_IFBLK: perms[0] = 'b'; break; case S_IFCHR: perms[0] = 'c'; break; case S_IFSOCK: perms[0] = 's'; break; case S_IFIFO: perms[0] = 'p'; break; default: perms[0] = '?'; break; } //========================================判断文件访问权限================================== //=================================st_mode和S_IRUSR等进行与操作============================= //文件所有者 perms[1] = (st.st_mode & S_IRUSR) ? 'r' : '-'; perms[2] = (st.st_mode & S_IWUSR) ? 'w' : '-'; perms[3] = (st.st_mode & S_IXUSR) ? 'x' : '-'; // 文件所在组 perms[4] = (st.st_mode & S_IRGRP) ? 'r' : '-'; perms[5] = (st.st_mode & S_IWGRP) ? 'w' : '-'; perms[6] = (st.st_mode & S_IXGRP) ? 'x' : '-'; // 其他人 perms[7] = (st.st_mode & S_IROTH) ? 'r' : '-'; perms[8] = (st.st_mode & S_IWOTH) ? 'w' : '-'; perms[9] = (st.st_mode & S_IXOTH) ? 'x' : '-'; //硬链接数 int linkNum = st.st_nlink; //文件所有者 char * fileUser = getpwuid(st.st_uid)->pw_name; //文件所在组 char * fileGrp = getgrgid(st.st_gid)->gr_name; //文件大小 long int fileSize = st.st_size; //修改时间 char * time = ctime(&st.st_mtime); //time最后有一个'\n' char mtime[512]={0}; strncpy(mtime,time,strlen(time)-1); char buf[1024]; sprintf(buf, "%s %d %s %s %ld %s %s", perms, linkNum, fileUser, fileGrp, fileSize, mtime, argv[1]); printf("%s\n", buf); return 0; }
文件属性操作函数
access()
chmod()
truncate()
chown()
改变文件所有者和组。
目录操作函数
rename()
chdir()
getcwd()
mkdir()
rmdir()
移除一个空目录
目录遍历函数:opendir(),readdir(),closedir()
示例:
#include <sys/types.h> #include <dirent.h> #include <stdio.h> #include <string.h> #include <stdlib.h> int getFileNum(const char * path); // 读取某个目录下所有的普通文件的个数 int main(int argc, char * argv[]) { if(argc < 2) { printf("%s path\n", argv[0]); return -1; } int num = getFileNum(argv[1]); printf("普通文件的个数为:%d\n", num); return 0; } // 用于获取目录下所有普通文件的个数 int getFileNum(const char * path) { // 1.打开目录 DIR * dir = opendir(path); if(dir == NULL) { perror("opendir"); exit(0); } struct dirent *ptr; // 记录普通文件的个数 int total = 0; while((ptr = readdir(dir)) != NULL) { // 获取名称 char * dname = ptr->d_name; // 忽略掉. 和.. if(strcmp(dname, ".") == 0 || strcmp(dname, "..") == 0) { continue; } // 判断是否是普通文件还是目录 if(ptr->d_type == DT_DIR) { // 目录,需要继续读取这个目录 char newpath[256]; sprintf(newpath, "%s/%s", path, dname); //printf("%s", newpath); total += getFileNum(newpath); } if(ptr->d_type == DT_REG) { // 普通文件 total++; } } // 关闭目录 closedir(dir); return total; }
运行结果:
dup() dup2() 复制文件描述符
fcntl()
示例:
#include <unistd.h> #include <fcntl.h> #include <stdio.h> #include <string.h> int main(){ //1.复制文件描述符 // int fd = open("a.txt",O_RDONLY); // int ret = fcntl(fd,F_DUPFD); //============================================== int fd = open("a.txt",O_RDWR); if(fd == -1){ perror("open"); return -1; } //2.获取文件描述符状态 int flag = fcntl(fd,F_GETFL); if(flag == -1){ perror("fcntl get"); return -1; } //3.修改文件描述符状态(需要先获取) flag |= O_APPEND; // flag = flag | O_APPEND, 给flag加入O_APPEND这个标记 int ret = fcntl(fd,F_SETFL,flag); if(ret == -1){ perror("fcntl set"); return -1; } const char * s = "\nheihei\n"; write(fd,s,sizeof(s)); close(fd); return 0; }
2023.7.14 晚