#includedup(复制文件描述符,主要是做保存作用) 头文件#include #include #include #include #include using namespace std; void isFile(const char* file_name); void openDir(const char* dir_name); int main(int argc, char** argv) { //判断用户输入 if (argc == 1) { isFile("."); } else { isFile(argv[1]); } return 0; } void isFile(const char* file_name) { // 获取文件属性 struct stat st; // stat 第二个参数为传出参数 int ret = stat(file_name, &st); if (ret == -1) { perror("int ret = stat(file_name, &st);"); exit(1); } if (S_ISDIR(st.st_mode)) { // 如果是目录打开目录 openDir(file_name); } cout << file_name << "t" << st.st_size << endl; } void openDir(const char* dir_name) { struct dirent* read_dir; string file_name; // 打开目录 DIR* dir = opendir(dir_name); if (!dir) { perror("DIR* dir = opendir(dir_name);"); exit(1); } while ((read_dir = readdir(dir))) { // 目录如果是.或..跳出结束本次循环,否则会进行无限递归 if (strcmp(read_dir->d_name, ".") == 0 || strcmp(read_dir->d_name, "..") == 0) { continue; } // 如果打开的还是目录进行递归,再次判断是否是目录 file_name = string(dir_name) + "/" + string(read_dir->d_name); isFile(file_name.data()); } closedir(dir); }
#include
int dup(int oldfd);
返回值成功返回新的文件描述符(新的文件描述符和旧的文件描述符打开的是同要给文件,也就是副本)
失败返回-1设置errno
案例#include#include #include using namespace std; int main(int argc, char** argv) { // 打开文件描述符为3 int fd = open(argv[1], O_RDONLY); if (fd == -1) { perror("int fd = open(argv[1], O_RDONLY);"); exit(1); } int new_fd = dup(fd); if (new_fd == -1) { perror("int new_fd = open(argv[1], O_RDONLY);"); exit(1); } // 返回文件描述符为4 cout << "new_fd = " << new_fd << endl; char read_buf[1024]; int read_count; while ((read_count = read(new_fd, read_buf, sizeof(read_buf)))) { if (read_count == -1) { perror("while ((read_count = read(new_fd, read_buf, sizeof(read_buf)))"); } cout << read_buf << endl; } close(fd); close(new_fd); return 0; }
dup2(重定向) 头文件
#include
int dup2(int oldfd, int newfd);
返回值成功返回新的文件描述符
失败返回-1
如果oldfd是无效的,newfd不会关闭
如果oldfd有效newfd是oldfd的副本(相当于两个指针指向同一个文件)
其实这个函数,就是新建一个指针然后通过新的指指针,通过旧的指针,对原指针指向的地址进行操作
当然也就可以,多个指针指向同一个地址
只是可以这样理解,但实际并不是.
案例#includefcntl实现dup2#include #include using namespace std; int main(int argc, char** argv) { int fd = open(argv[1], O_RDWR | O_CREAT ,0664); if (fd == -1) { perror("int fd = open(argv[1], O_RDWR | O_CREAT ,0664);"); exit(1); } int fd2 = open(argv[2], O_RDWR | O_CREAT, 0664); if (fd2 == -1) { perror("int fd2 = open(argv[1], O_RDWR | O_CREAT ,0664);"); exit(1); } dup2(fd, fd2); write(fd2, "asljfdfjsdklf", 13); // 将标准输出重定向到文件 dup2(fd, STDOUT_FILENO); cout << "asljfdfjsdklf" << endl; return 0; }
同样可以得到新的文件描述符
案例#include#include #include using namespace std; int main(int argc, char** argv) { int fd = open(argv[1], O_RDWR | O_CREAT ,0664); if (fd == -1) { perror("int fd = open(argv[1], O_RDWR | O_CREAT ,0664);"); exit(1); } // 因为0(标准输入)已被占用所以返回可用的最小文件描述符 int new_fd = fcntl(fd, F_DUPFD, 0); cout << new_fd << endl; // 4 // 会返回一个大于等于10(因为10也有可能被占用)的文件描述符 new_fd = fcntl(fd, F_DUPFD, 10); cout << new_fd << endl; // 10 new_fd = fcntl(fd, F_DUPFD, 10); cout << new_fd << endl; // 11 return 0; }
文件IO就到这里了,其实文件IO就是文件的读写,目录的读写.无论实现什么功能都是基于这两个嘛.
其他有个印象现用现查,无论记的再熟悉,一个月不用也会忘.



