区别:标准c库的io函数是可以跨平台的原因是调用不同平台的系统api
标准c库文件i/o是有缓冲区的对磁盘读写可以提高效率
网络环境要求速度高不能用缓冲区要用linux读写文件
下图显示了c库io和linux系统io的关系
虚拟地址空间:并不存在是一种设想 解释编程中的模型
文件描述符
文件描述表是一个数组大小默认是1024
5.linux系统io函数
open:
1.打开一个已经存在的文件
/*
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
//打开一个已经存在的文件
int open(const char *pathname, int flags);
参数:
pathname:要打开的文件路径
flags:对文件的操作权限设置
O_RDONLY, O_WRONLY, or O_RDWR 这三个设置是互斥的
返回值:成功返回新的文件描述符如果调用失败会返回-1(产生错误)
errno:属于Linux系统函数库,库里面一个全局变量,记录的是最近的错误号。
#include <stdio.h>
void perror(const char *s);作用:打印errno对应的错误描述
s参数:用户描述,比如hello,最终输出的内容是 hello:xxx(实际的错误描述)
#include <unistd.h>
int close(int fd);作用:关闭文件描述符
*/
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>
#include<unistd.h>
int main()
{
int fd=open("a.txt",O_RDONLY);
if(fd==-1)//由于不存在a.txt所以会报错
{
perror("open");//输出错误信息
}
//关闭文件描述符
close(fd);
return 0;
}
2.创建一个文件
/*
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags, mode_t mode);
参数:
-pathname:要创建的文件路径
-flags
-必选项:O_RDONLY, O_WRONLY, or O_RDWR
-可选项:O_CREAT 文件不存在创建新文件
-mode:八进制的数,表示用户对创建出的新的文件的操作权限 比如:0775 0表示八进制数
最终权限是 mode & ~umask(作用:抹去某些权限)
0777 & (umask=0002)0775=0775
flags参数是一个int类型的数据,占4个字节,32位
flags 32个位,每一位就是一个标志位
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<stdio.h>
#include<unistd.h>
int main()
{
int fd=open("create.txt",O_RDWR|O_CREAT,0777);
if(fd==-1)
{
perror("open");
}
//关闭
close(fd);
}
read:从文件读取数据到内存当中
/*
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
参数:
-fd:文件描述符,open得到的,可以通过这个文件描述符操作某个文件
-buf:需要读取数据存放的地方,数组的地址(传出参数)
-count:指定的数组的大小
返回值:
-成功:
>0:返回实际读取到的字节数
=0:文件已经读取完了
-失败:
-1,并且设置errno
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
参数:
-fd:文件描述符,open得到的,通过这个文件描述符操作某个文件
-buf:要往磁盘写入的数据
-count:要写的数据的实际的大小
返回值:
成功:实际写入的字节数
失败:-1,并设置errno
*/
#include <unistd.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{
//通过open打开english.txt
int srcfd = open("english.txt",O_RDONLY);
if(srcfd==-1)
{
perror("open");
return -1;
}
//创建一个新的文件(拷贝文件)
int destfd=open("cpy.txt",O_WRONLY|O_CREAT,0664);
if(destfd==-1)
{
perror("open");
return -1;
}
//频繁的读写文件
char buf[1024]={0};
int len = 0;
while((len=read(srcfd,buf,sizeof(buf)))>0)
{
write(destfd,buf,len);
}
//关闭文件
close(destfd);
close(srcfd);
return 0;
}
lseek:操作文件指针
/*
标准c库的函数
#include <stdio.h>
int fseek(FILE *stream, long offset, int whence);
Linux系统函数
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
参数:
-fd:文件描述符,通过open得到的,通过这个fd操作某个文件
-offset:偏移量
-whence:
SEEK_SET
设置文件指针的偏移量
SEEK_CUR
设置偏移量:当前位置+第二个参数offset的值
SEEK_END
设置偏移量:文件大小+第二个参数offset的值
返回值:返回文件指针的位置
作用
1.移动文件指针到文件头
lseek(fd,0,SEEK_SET);
2.获取当前文件指针的位置
lseek(fd,0,SEEK_CUR);
3.获取文件长度
lseek(fd,0,SEEK_END);
4.拓展文件的长度,当前文件10b,110b,增加了100个字节
lseek(fd,100,SEEK_END);
注意:需要写一次文件的数据
*/
#include <sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include <unistd.h>
#include<stdio.h>
int main()
{
int fd=open("hello.txt",O_RDWR);
if(fd==-1)
{
perror("open");
return -1;
}
//拓展文件长度
int ret=lseek(fd,100,SEEK_END);
if(ret==-1)
{
perror("lseek");
return -1;
}
//写入一个空数据
write(fd,"",1);
//关闭文件
close(fd);
return 0;
}
stat:查看文件信息
/*
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *pathname, struct stat *statbuf);
作用:获取一个文件相关的信息
参数:
-pathname:操作的文件的路径
-statbuf:结构体变量,传出参数,用于保存获取到的文件的信息
返回值:
成功:返回0
返回:-1 设置errno
int lstat(const char *pathname, struct stat *statbuf);
作用:获取软连接文件的信息
参数:
-pathname:操作的文件的路径
-statbuf:结构体变量,传出参数,用于保存获取到的文件的信息
返回值:
成功:返回0
返回:-1 设置errno
*/
#include<sys/types.h>
#include<sys/stat.h>
#include<stdio.h>
#include<unistd.h>
int main(){
struct stat statbuf;
int ret=stat("a.txt",&statbuf);
if(ret==-1)
{
perror("stat");
return -1;
}
printf("size:%ld\n",statbuf.st_size);
return 0;
}