标准IO完结

This commit is contained in:
lzy
2024-04-27 16:55:56 +08:00
parent 808ec80a62
commit d2136d1f26
4 changed files with 216 additions and 3 deletions

View File

@@ -8,7 +8,7 @@
优先使用标准IO兼容性更好还有合并系统调用的优势。 优先使用标准IO兼容性更好还有合并系统调用的优势。
## 标准IO
```c ```c
/* stdio */ /* stdio */
@@ -150,9 +150,116 @@ fflush();
* _IOLBF * _IOLBF
* _IOFBF * _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 <stdio.h>
*
* !!! 里面有 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 ## 文件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/目录

View File

@@ -0,0 +1 @@
CFLAGS+=-D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE

View File

@@ -0,0 +1,40 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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);
}

65
Chapter13/io/sys/mycpy.c Normal file
View File

@@ -0,0 +1,65 @@
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#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 <src> <dst>\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);
}