From d2136d1f2690b8f1b0714ccdbc4322179e0b4b94 Mon Sep 17 00:00:00 2001 From: lzy Date: Sat, 27 Apr 2024 16:55:56 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=87=E5=87=86IO=E5=AE=8C=E7=BB=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Chapter13/C13-Linux系统编程学习笔记.md | 113 ++++++++++++++++++++++++- Chapter13/io/stdio/Makefile | 1 + Chapter13/io/stdio/getline.c | 40 +++++++++ Chapter13/io/sys/mycpy.c | 65 ++++++++++++++ 4 files changed, 216 insertions(+), 3 deletions(-) create mode 100644 Chapter13/io/stdio/Makefile create mode 100644 Chapter13/io/stdio/getline.c create mode 100644 Chapter13/io/sys/mycpy.c diff --git a/Chapter13/C13-Linux系统编程学习笔记.md b/Chapter13/C13-Linux系统编程学习笔记.md index cd930c1..c1b61ce 100644 --- a/Chapter13/C13-Linux系统编程学习笔记.md +++ b/Chapter13/C13-Linux系统编程学习笔记.md @@ -8,7 +8,7 @@ 优先使用标准IO,兼容性更好,还有合并系统调用的优势。 - +## 标准IO ```c /* stdio */ @@ -150,9 +150,116 @@ fflush(); * _IOLBF * _IOFBF */ -int setvbuf(FIEL *stream, char *buf, int mode, size_t size); +int setvbuf(FILE *stream, char *buf, int mode, size_t size); + +/** + * 为了读取一行 + * + * 使用办法: + * #define _GNU_SOURCE 这个不想写到代码里面的话可以写到makefile + * eg. CFLAGS+=-D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE + * #include + * + * !!! 里面有 malloc 动作,未释放 + * !!! 是方言,可以自己封装一个mygetline和mygetline_free + * +*/ +ssize_t getline(char **lineptr, size_t *n, FILE *stream); + +/** + * 临时文件 + * 1. 如何不冲突的创建 + * 2. 及时销毁 + * + * tmpnam: 创建临时文件名字 + * 有并发危险,因为产生名字和创建文件是两步 + * + * tmpfile: 创建临时文件 + * 是匿名文件,ls -a 都看不到 + * 避免冲突 +*/ +char *tmpnam(char *s); +FILE *tmpfile(void); + + ``` -P131 \ No newline at end of file +## 文件IO/系统调用IO + +文件描述符(`fd`)是在文件IO中贯穿始终的类型。 + +### 文件描述符的概念 +是一个整型数,是一个指针数组的下标。 +优先使用当前可用范围内最小的。 + +### 文件IO操作相关函数: +- open +- close +- read +- write +- lsee + +```c + +/** + * r -> O_RDONLY + * r+ -> O_RDWR + * w -> O_WRONLY | O_CREAT | O_TRUNC + * w+ -> O_RDWR | O_TRUNC | O_CREAT + * + * 如果有creat就必须用三参数的形式 + * C语言没有重载,这是变参函数 + * + * @prarm: pathname 文件路径 + * @prarm: flags 文件打开方式 + * @prarm: mode 文件权限 + * +*/ +int open(const char *pathname, int flags); +int open(const char *pathname, int flags, mode_t mode); + +int close(int fd); + +/** + * read from a file descriptor + * + * @return 读取的字节数,失败返回-1 +*/ +ssize_t read(int fd, void *buf, size_t count); + +/** + * write to a file descriptor + * + * @return 写入的字节数,失败返回-1 +*/ +ssize_t write(int fd, const void *buf, size_t count); + +/** + * 移动文件指针 + * + * @prarm: offset 移动多远 + * @prarm: whence 移动方向 + * SEEK_SET, SEEK_CUR, SEEK_END + * + * @return 成功0,失败-1 +*/ +off_t lseek(int fd, offt offset, int whence); + +``` + + +### 文件IO与标准IO的区别 + +### IO的效率问题 + +### 文件共享 + +### 原子操作 + +### 程序中的重定向:`dup`, `dup2` + +### 同步:`sync`, `fsync`, `fdatasync`, `fcntl`, `ioctl` + +### /dev/fd/目录 \ No newline at end of file diff --git a/Chapter13/io/stdio/Makefile b/Chapter13/io/stdio/Makefile new file mode 100644 index 0000000..9dc73e4 --- /dev/null +++ b/Chapter13/io/stdio/Makefile @@ -0,0 +1 @@ +CFLAGS+=-D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE \ No newline at end of file diff --git a/Chapter13/io/stdio/getline.c b/Chapter13/io/stdio/getline.c new file mode 100644 index 0000000..9f82c67 --- /dev/null +++ b/Chapter13/io/stdio/getline.c @@ -0,0 +1,40 @@ +#include +#include +#include + +int main(int argc, char **argv) +{ + FILE *fp; + char *linebuf; + size_t linesize; + + if (argc < 2) + { + fprintf(stderr, "Usage...\n"); + exit(1); + } + + fp = fopen(argv[1], "r"); + if (NULL == fp) + { + perror("fopen()"); + exit(1); + } + + // !!! + linebuf = NULL; + linesize = 0; + + while (1) + { + if (getline(&linebuf, &linesize, fp) < 0) + break; + printf("%d\n", strlen(linebuf)); + printf("%d\n", linesize); + // 此时输出linesize值不对,是因为没有初始化 + // 修改后发现,linesize初始值就是120,是后面不够再增加 + } + + fclose(fp); + exit(0); +} \ No newline at end of file diff --git a/Chapter13/io/sys/mycpy.c b/Chapter13/io/sys/mycpy.c new file mode 100644 index 0000000..76b61b8 --- /dev/null +++ b/Chapter13/io/sys/mycpy.c @@ -0,0 +1,65 @@ +#include +#include +#include +#include + +#define BUFSIZE 1024 + +int main(int argc, char **argv) +{ + int sfd, dfd; + char buf[BUFSIZE]; + int len, ret, pos; + + if (argc < 3) + { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(1); + } + + sfd = open(argv[1], O_RDONLY); + if (sfd < 0) + { + perror("open"); + exit(1); + } + + dfd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0600); + if (dfd < 0) + { + // !!! + close(sfd); + perror("open"); + exit(1); + } + + while (1) + { + len = read(sfd, buf, BUFSIZE); + if (len < 0) + { + perror("read"); + break; + } + if (len == 0) + break; + + pos = 0; + while (len > 0) + { + ret = write(dfd, buf + pos, len); + if (ret < 0) + { + perror("write"); + exit(1); + } + pos += ret; + len -= ret; + } + } + + close(dfd); + close(sfd); + + exit(0); +} \ No newline at end of file