在一开始接触到Linux的时候,我们经常接触到的系统IO函数有下列这几个
open()函数,write()函数,read()函数,lseek()函数,close()函数
open()函数,write()函数,read()函数,lseek()函数,close()函数
下面我们将逐个探究一下:
open函数: 打开或创建一个文件
库和函数原型:
#include<fcntl.h>
int open(const char* pathname,int flag, ... /*mode_t mode*/)
库和函数原型:
#include<fcntl.h>
int open(const char* pathname,int flag, ... /*mode_t mode*/)
我们将第三个参数写为...,是因为ISO C用这种方法表明余下的参数机器类型将根据具体的调用有所不同。
对于open函数, 只有在创建新文件的时候才会使用到第三个参数。
对于open函数, 只有在创建新文件的时候才会使用到第三个参数。
解析:
返回值:
成功返回一个整型(int)的文件描述符,这个文件描述符可以看作是一个打开文件的钥匙,凡是对文件的操作都离不开它。
错误返回-1
这个 文件描述符一定是用最小的未使用的描述符数值,其中0,1,2分别是标准输入stdin,标准输出stdout和标准出错输出stderr,所以我们在不修改或者关闭其中三个的情况下,打印出的第一个描述符数值一般是3
成功返回一个整型(int)的文件描述符,这个文件描述符可以看作是一个打开文件的钥匙,凡是对文件的操作都离不开它。
错误返回-1
这个 文件描述符一定是用最小的未使用的描述符数值,其中0,1,2分别是标准输入stdin,标准输出stdout和标准出错输出stderr,所以我们在不修改或者关闭其中三个的情况下,打印出的第一个描述符数值一般是3
参数:
pathname:要打开或者创建的文件名。
flag :打开方式的选项,用下来一个或多个常量进行或|运算构成的flag参数。
选项: O_RDONLY, O_WRONLY, O_RDWR 这三个常量必须有且只能选一个
O_CREAT:文件不存在则创建
O_TRUNC:若文件存在,则把数据清零。
上面这几个是常用到的,其它的选项可以自行man了解。
这几个常量对应数值O_RDONLY----0, O_WRONLY----1, O_RDWR----2, O_CREAT----4
使用它们 注意进行或|运算之后的结果。
pathname:要打开或者创建的文件名。
flag :打开方式的选项,用下来一个或多个常量进行或|运算构成的flag参数。
选项: O_RDONLY, O_WRONLY, O_RDWR 这三个常量必须有且只能选一个
O_CREAT:文件不存在则创建
O_TRUNC:若文件存在,则把数据清零。
上面这几个是常用到的,其它的选项可以自行man了解。
这几个常量对应数值O_RDONLY----0, O_WRONLY----1, O_RDWR----2, O_CREAT----4
使用它们 注意进行或|运算之后的结果。
mode:它其实是一个8进制数,说明你将要创建文件的权限
例:0777则代表-rwxrwxrwx
例:0777则代表-rwxrwxrwx
write函数:往打开的文件里面写数据
库和函数原型:
#include <unistd.h>
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
解析:
返回值:成功则返回已写的字节数,错误返回-1
返回值:成功则返回已写的字节数,错误返回-1
fd: open函数返回的文件描述符
buf: 要写入数据的地址,通常是已声明的字符串的首地址
count:一次要写几个字节,通常为strlen()个
buf: 要写入数据的地址,通常是已声明的字符串的首地址
count:一次要写几个字节,通常为strlen()个
代码块:
#include<unistd.h>
#include<sys/types.h>
#include<fcntl.h>
#include<string.h>
#include<stdio.h>
#include<sys/stat.h>
int main()
{
int fd=open("./log",O_WRONLY|O_CREAT,775);//以只写的形式创建mylog
if(fd==-1)
{
perror("open fail!\n");
return -1;
}
const char*msg="Hello Koma\n";
int i=0;
while(i<10)
{
write(fd,msg,strlen(msg));
i++;
}
printf("%s\n",msg);
close(fd);
}
运行结果截图:


read函数: 从打开的设备或文件中读取数据。
库和函数原型:
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
返回值: 成功返回读取的字节数,出错返回-1并设置errno,0表示文件末端
如果在调read之前已到达文件末尾,则这次read返回0
如果要求读100个字节,而离文件末尾只有99个字节,则read返回99,下一次再调用read返回0
参数: 可联系write函数记忆
fd: 文件描述符
buf: 要读数据的地址,通常是已声明的字符串的首地址
count 一次要读多少个数据
举个例子:在终端读入并写出
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{
char*buf[10];
size_t st=read(STDIN_FILENO,buf,10);//STDIN标准输入
if(st<0)
{
printf("read fail!\n");
}
write(STDOUT_FILENO,buf,st);//标准输出
printf("\n");
return 0;
}
运行结果:

lseek函数: 显式地为一个打开的文件设置偏移量,通常读写操作都是从当前文件偏移量处开始的,并使偏移量增加所读写的字节数
库和函数原型:
#include <unistd.h>
#include <sys/types.h>
#include <sys/types.h>
off_t lseek(int fd, off_t offset, int whence);
返回值:
成功返回新的文件偏移量注意可能负数,出错返回-1
如果文件 描述符引用的是一个管道,FIFO或者 网络套接字,则lseek返回-1,,并将error设置成ESPIPE
如果文件 描述符引用的是一个管道,FIFO或者 网络套接字,则lseek返回-1,,并将error设置成ESPIPE
参数:
fd: 文件描述符
offset 的含义取决于参数 whence
whence有三个选项:
1. 如果 whence 是 SEEK_SET, 文件偏移量将被设置为 0加上 offset。
2. 如果 whence 是 SEEK_CUR,文件偏移量将被设置为 当前值 加上 offset,offset 可以为正也可以为负。
3. 如果 whence 是 SEEK_END,文件偏移量将被设置为文件长度加上 offset,offset 可以为正也可以为负。
fd: 文件描述符
offset 的含义取决于参数 whence
whence有三个选项:
1. 如果 whence 是 SEEK_SET, 文件偏移量将被设置为 0加上 offset。
2. 如果 whence 是 SEEK_CUR,文件偏移量将被设置为 当前值 加上 offset,offset 可以为正也可以为负。
3. 如果 whence 是 SEEK_END,文件偏移量将被设置为文件长度加上 offset,offset 可以为正也可以为负。
注意:
lseek 仅将文件偏移量保存于内核中,不会导致任何 I/O 操作。这个文件偏移量将被用于之后的读写操作。
lseek 仅将文件偏移量保存于内核中,不会导致任何 I/O 操作。这个文件偏移量将被用于之后的读写操作。
文件偏移量可以大于当前文件长度,在这之上,对文件的下一次写操作就会在文件中(源文件末端到新开始的位置)构成空洞,并被读成0,且文件中的空洞并不占用磁盘的内存空间。
代码块:
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{
int fd=open("./fish",O_RDWR|O_CREAT,0777);
if(fd<0)
{
perror("open");
printf("open fail!");
return -1;
}
char msg[100] = "this is msg\n";
write(STDOUT_FILENO,msg,strlen(msg));//在标准输出窗口写数据
write(fd,msg,12);//在新创建的fish里面写数据
lseek(fd, 0,SEEK_SET);//把偏移量设置成0,要是把0换成strlen(msg)-->r=0;
int r = read(fd,msg,100);//从开始出开始读数据
printf("r=%d\n", r);
close(fd);
return 0;
}
运行结果:

close(fd)函数: 关闭这个已打开的文件,这个就没什么好说的了吧。。。
上面大概就是我在学习系统IO函数的时候的一点小结,其实就是把握好这个文件描述符就好了,参数这个东西用多了就熟练了。。