系统IO
二、(sysio)文件IO
文件描述符使用策略:优先使用最小的
1、open()
函数功能:使用给定的模式flags打开pathname所指定的文件
函数原型:( $: man 2 open --> 手册 )
-
当文件存在时
int open(const char* pathname,int flags) // //只要有open就会产生一个结构体,然后去调用它,返回给用户一个整型数文件描述符。 //拿到的是一个文件描述符,然后通过描述符引用结构体。
-
当文件不存在时(flag --> O_CREAT)
int open (const char *pathname, int flags, mode_t mode) //返回值:成功 --> 文件描述符 失败 --> -1 //文件描述符使用策略:优先使用当前可用范围内最小的id
参数:
┌─────────────┬───────────────────────────────┐
│fopen() mode │ open() flags │
├─────────────┼───────────────────────────────┤
│ r │ O_RDONLY │
├─────────────┼───────────────────────────────┤
│ w │ O_WRONLY | O_CREAT | O_TRUNC │
├─────────────┼───────────────────────────────┤
│ a │ O_WRONLY | O_CREAT | O_APPEND │
├─────────────┼───────────────────────────────┤
│ r+ │ O_RDWR │
├─────────────┼───────────────────────────────┤
│ w+ │ O_RDWR | O_CREAT | O_TRUNC │
├─────────────┼───────────────────────────────┤
│ a+ │ O_RDWR | O_CREAT | O_APPEND │
└─────────────┴───────────────────────────────┘
flags | 含义 |
---|---|
O_RDONLY | 只读 |
O_WRONLY | 只写 |
O_CREAT | 无则创建 |
O_TRUNC | 有则清空 |
O_APPEND | 追加 |
O_RDWR | 可读可写 |
2、close()
int close(int fd)
//返回值:成功:0 失败:-1
3、read()
函数功能:从fd所指向的文件中读count个字节到buff缓存区
ssize_t read(int fd,void *buff,size_t count)
//<unistd.h>
返回值
成功:
- count:成功读取全部字节
- 0~count:
- 剩余文件长度小于count
- 读取期间被异步信号打断
失败:
- -1,读取错误
4、write()
函数功能:从fd所指向的文件中写入count个字节到buff缓存区
ssize_t write(int fd,void *buff,size_t count)
//<unistd.h>
返回值
成功:
- count:成功写入全部字节
- 0~count:
- 写入期间被异步信号打断
失败:
- -1,读取错误
函数测试:实现文件拷贝
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define BUFSIZE 1024
int main(int argc,char *argv[])
{
int sfd,dfd;
char buf[BUFSIZE];
ssize_t len,ret,pos;
if(argc < 3)
{
fprintf(stderr,"Usage:%s srcfile destfile\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)
{
perror("fopen()");
exit(1);
}
while(1)
{
len = read(sfd,buf,BUFSIZE); //每次循环成功拷贝len个字节
if(len == 0)
break;
if(len < 0)
{
perror("read()");
exit(1);
}
//len > 0
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);
}
5、lseek()
函数功能:设置文件读写位置
off_t lseek(int fd,off_t offset,int whence)
//返回值:成功 --> 文件偏移位置值 失败 --> -1
- 若whence为SEEK_SET,基准点为文件开头
- 若whence为SEEK_CUR,基准点为当前位置
- 若whence为SEEK_END,基准点为文件末尾
6、dup()
函数功能:复制文件描述符oldfd
int dup(int oldfd); //oldfd已有的文件描述符
代码应用:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
int fd;
fd = open("/tmp/out",O_WRONLY|O_CREAT|O_TRUNC,0600);
if(fd < 0)
{
perror("open()");
exit(1);
}
close(1);
dup(fd);
close(fd);
//---------------------------------------------
puts("Hello!");
exit(0);
}
7、dup2()
函数功能:将一个描述符oldfd复制到newfd
int dup2(int oldfd, int newfd);
代码应用:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
int fd;
fd = open("/tmp/out",O_WRONLY|O_CREAT|O_TRUNC,0600);
if(fd < 0)
{
perror("open()");
exit(1);
}
dup2(fd,1);
if(fd != 1)
close(fd);
//---------------------------------------------
puts("Hello!");
exit(0);
}
8、fileno()
int fileno(FILE *stream);
//The function clearerr() clears the end-of-file and error indicators for
//the stream pointed to by stream.
复制普通文件小实验
1、打开要复制的文件
2、创建新的文件
3、把源文件内容读到缓冲区,把缓冲区内容写入新文件
4、循坏执行第三步,直到读取的字节数量为0,退出循坏。
5、关闭打开的文件