标准IO完结
This commit is contained in:
@@ -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 <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/目录
|
||||
1
Chapter13/io/stdio/Makefile
Normal file
1
Chapter13/io/stdio/Makefile
Normal file
@@ -0,0 +1 @@
|
||||
CFLAGS+=-D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
|
||||
40
Chapter13/io/stdio/getline.c
Normal file
40
Chapter13/io/stdio/getline.c
Normal 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
65
Chapter13/io/sys/mycpy.c
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user