ssize_t read(int fd, void *buf, size_t count);
返回值
如果出现错误,返回-1
读文件结束,返回0
否则返回从该文件复制到规定的缓冲区中的字节数
ssize_t write(int fd, const void *buf, size_t count);
返回值
如果出现错误,返回-1
如果写入成功,则返回写入到文件中的字节个数
下面是一个简单的从一个文件中读取内容写入到另一个文件中去:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #define ERR_EXIT(m) \ do \ { \ perror (m); \ exit (EXIT_FAILURE); \ } while (0) int main( int argc, char *argv[]) //这里用传参传入原文件和目标文件 { int infd; int outfd; if (argc != 3) { fprintf (stderr, "Usage %s src dest\n" , argv[0]); exit (EXIT_FAILURE); } infd = open(argv[1], O_RDONLY); //打开原文件 if (infd == -1) ERR_EXIT( "open src error" ); //打开目标文件 if ((outfd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) ERR_EXIT( "open dest error" ); char buf[1024]; int nread; while ((nread = read(infd, buf, 1024)) > 0) { write(outfd, buf, nread); } close(infd); close(outfd); return 0; } |
值得注意的是在用完文件描述符后最好的习惯就是关闭,做到随用随关。
要做到文件的随机读写就要涉及到另一个系统调用lseek了:
off_t lseek (int fd, off_t offset, int base);
fd:需设置的文件标识符
ofset:偏移量
base:搜索的起始位置
base |
文件位置 |
SEEK_SET |
从文件开始处计算偏移 |
SEEK_CUR |
从当前文件的偏移值计算偏移 |
SEEK_END |
从文件的结束处计算偏移 |
看一个小例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #define ERR_EXIT(m) \ do \ { \ perror (m); \ exit (EXIT_FAILURE); \ } while (0) int main( void ) { int fd; fd = open( "test.txt" , O_RDONLY); if (fd == -1) ERR_EXIT( "open error" ); char buf[1024] = {0}; int ret = read(fd, buf, 5); if (ret == -1) ERR_EXIT( "read error" ); printf ( "buf=%s\n" , buf); ret = lseek(fd, 0, SEEK_CUR); //从当前位置偏移0个量即获取当前偏移位置 if (ret == -1) ERR_EXIT( "lseek" ); printf ( "current offset=%d\n" , ret); return 0; } |
下面介绍一下目录的相关操作:
DIR* opendir(char *pathname);
pathname:目录的路径,路径可以是相对的也可以是绝对的
打开成功,返回一个目录指针
打开失败,则返回0
下面是涉及到访问打开的目录中的一些连接的细节:
struct dirent* readdir(DIR *dirptr);
这里用到了打开目录返回的DIR指针
返回一个指向dirent结构的指针,它包含指定目录中下一个连接的细节;
没有更多连接时,返回0
当然最后也是一样,打开目录,用完了也要习惯的关闭一下:
int closedir (DIR *dirptr);
struct dirent
{
long d_ino;
off_t d_off;
unsigned short d_reclen;
char d_name [NAME_MAX+1]; //这是我们比较关心和常用的就是目录下的文件名字
}
下面是一个实现基本ls功能的小程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <dirent.h> #define ERR_EXIT(m) \ do \ { \ perror (m); \ exit (EXIT_FAILURE); \ } while (0) int main( void ) { DIR *dir = opendir( "." ); //打开当前目录 struct dirent *de; //定义一个包含文件细节的结构题 while ((de = readdir(dir)) != NULL) //循环读取目录中的信息 { if ( strncmp (de->d_name, "." , 1) == 0) //这个起到过滤以.开始的文件 continue ; printf ( "%s\n" , de->d_name); } closedir(dir); //最后关闭 exit (EXIT_SUCCESS); //和return 0作用类似 } |
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
· 开发的设计和重构,为开发效率服务
· 从零开始开发一个 MCP Server!
· Ai满嘴顺口溜,想考研?浪费我几个小时
· .NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密