首先说明一点,这些所有的Linux的IO系统调用函数的头文件都不需要自己死记硬背的,可以通过查阅man手册来查看.
Linux系统IO用法一般通过man 2 xx来查看
标准C库系统IO一般使用man 3 xx来查看
这里既然提到了,那就简单说下Linux系统io和标准库io的主要区别:
Linux系统io和标准C库io的主要区别
1.标准C库io相较于linux的io多了一个io缓冲区,用来暂时存储数据.所以通常比linux的io操作更靠谱安全,效率更高。但是在网络通信方便,由于多了一个io缓冲区,所以考虑效率问题,大部分还是选择的Linux的IO中的socket(tcp udp)来进行.
2.标准C库io使用与几乎目前所有的主流操作系统:Windowns、Linux等等
下列所有的Linux系统IO调用函数,我都使用了实例可运行的代码来进行讲解,上面的笔记也是我一个一个总结出来的,希望大家结合起来看,能帮到大家
open
A. int open(const char *pathname, int flags);
参数:
1.要打开的文件路径
2.设置文件的权限:O_RDONLY, O_WRONLY, or O_RDWR,这三种方式互斥
返回值:整数型的文件描述符或者-1
perror:标准库IO中描述错误的系统调用函数
void perror(const char *s); //输出错误信息 :xxxx
B.int open(const char *pathname, int flags, mode_t mode);
参数:
@param1:要创建的文件的路径
@param2:文件的操作权限 (比选项):O_RDONLY, O_WRONLY, or O_RDWR,这三种方式互斥
可选项:O_CREAT 文件不存在就创建新文件
@param3:八进制的数,表示用户对创建的新的文件的操作权限,比如:0775
最终权限: mode & ~umask
0777(三通道:读写可执行都打开) umask:0002-> ~umask:0777-0002=0775
0777: 111111111
& 0775: 111111101
111111101->0775
uamsk作用:抹去某些权限,让创建的文件权限更加合理
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
/*
**********************************************************
//主要用来打开已经存在的文件
int open(const char *pathname, int flags);
参数:
1.要打开的文件路径
2.设置文件的权限:O_RDONLY, O_WRONLY, or O_RDWR,这三种方式互斥
返回值:整数型的文件描述符或者-1
perror:标准库IO中描述错误的系统调用函数
void perror(const char *s); //输出错误信息 :xxxx
***********************************************************
int open(const char *pathname, int flags, mode_t mode);
参数:
@param1:要创建的文件的路径
@param2:文件的操作权限 (比选项):O_RDONLY, O_WRONLY, or O_RDWR,这三种方式互斥
可选项:O_CREAT 文件不存在就创建新文件
@param3:八进制的数,表示用户对创建的新的文件的操作权限,比如:0775
最终权限: mode & ~umask
0777(三通道:读写可执行都打开) umask:0002-> ~umask:0777-0002=0775
0777: 111111111
& 0775: 111111101
111111101->0775
uamsk作用:抹去某些权限,让创建的文件权限更加合理
***********************************************************
*/
int main()
{
int fd = open("./a.txt",O_RDWR | O_CREAT, 0777); //没有文件就创建文件
if(fd == -1)
{
perror("open");
}
else
{
printf("open sucefully!\n");
}
close(fd);
return 0;
}
read和write
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
/*
ssize_t read(int fd, void *buf, size_t count);
参数:
@param1:文件描述符,open得到,可以通过这个文件描述符对文件进行操作
@param2:缓冲区,读取数据存放的地方(传出参数)
@param3:指定的数组大小
返回值:
成功:
>0 返回实际读取到的字节数目
=0:文件以及读完了
失败:返回-1,并且设置errno
ssize_t write(int fd, const void *buf, size_t count);
参数:
@param1:文件描述符,open得到,可以通过这个文件描述符对文件进行操作
@param2:要往磁盘写入的数据,数据
@param3:指写的数据实际的大小
返回值:
成功:
>0 返回实际写入的字节数目
失败:返回-1,并且设置errno
*/
int main()
{
int fd1 = open("./english.txt",O_RDONLY);
if(fd1 == -1)
{
perror("open fd1");
exit(-1);
}
//创建一个新的拷贝文件
int fd2 = open("result.txt",O_RDWR | O_CREAT,0664);
if(fd2 == -1)
{
perror("open and create fd2");
exit(-1);
}
//读
char read_buff[1024] = {0};
int len = 0;
while((len = read(fd1,read_buff,sizeof(read_buff))) > 0)
{
write(fd2,read_buff,len); //读到多少写多少
}
close(fd1);
close(fd2);
}
lseek
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
Linux系统函数
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
参数:
fd:通过open得到的文件描述符
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,增加100b
lseek(fd,100,SEEK_END);
如果要想扩展文件,移动了指针还需要在后面写入空数据
返回值:
返回文件指针的位置
标准库fseek
#include <stdio.h>
int fseek(FILE *stream, long offset, int whence);
*/
int main()
{
int fd = open("hello.txt",O_RDWR);
if(fd == -1)
{
perror("open");
exit(-1);
}
int ret = lseek(fd,100,SEEK_END); //扩展文件大小
if(ret == -1)
{
perror("lseek");
exit(-1);
}
//如果要想扩展文件,移动了指针还需要在后面写入空数据
write(fd," ",1);
printf("%d\n",ret);
close(fd);
return 0;
}
stat和lstat
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
/*
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *pathname, struct stat *statbuf);
作用:获取一个文件相关的信息
参数:
1.操作的文件的路径
2.结构体变量,传出参数,用于保存获取到的文件的信息
返回值:
1.成功:0
2.失败:-1
int lstat(const char *pathname, struct stat *statbuf);
参数:
1.操作的文件的路径
2.结构体变量,传出参数,用于保存获取到的文件的信息
返回值
1.成功:0
2.失败:-1
*/
int main()
{
struct stat statbuf;
int ret = stat("a.txt",&statbuf);
if(ret == -1)
{
perror("stat");
exit(-1);
}
printf("size:%ld\n",statbuf.st_size);
return 0;
}
/*
创建软连接: ln -s a.txt b.txt
可以用lstat 获取他的信息,但是stat 获取不的是这个软连接对应的a.txt信息
*/
/*
模拟实现ls -l 指令
-rw-rw-r-- 1 zbz zbz 12 10月 3 19:15 a.txt
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <string.h>
int main(int argc, char *argv[])
{
struct stat statbuf;
if(argc < 2)
{
printf("%s filename\n",argv[0]);
exit(-1);
}
int ret = stat(argv[1],&statbuf);
if(ret == -1)
{
perror("stat");
exit(-1);
}
//获取文件类型和文件权限
char perms[11] = {0}; //用于保存文件类型和文件权限的字符串
switch(statbuf.st_mode & __S_IFMT)
{
case __S_IFLNK:
perms[0] = 'l';
break;
case __S_IFDIR:
perms[0] = 'd';
break;
case __S_IFREG:
perms[0] = '-';
break;
case __S_IFBLK:
perms[0] = 'b';
break;
case __S_IFCHR:
perms[0] = 'c';
break;
case __S_IFSOCK:
perms[0] = 's';
break;
case __S_IFIFO:
perms[0] = 'p';
break;
default:
perms[0] = '?';
break;
}
//判断文件访问权限
//文件所有者
perms[1] = (statbuf.st_mode & S_IRUSR) ? 'r':'-';
perms[2] = (statbuf.st_mode & S_IWUSR) ? 'w':'-';
perms[3] = (statbuf.st_mode & S_IXUSR) ? 'x':'-';
//文件所在组
perms[4] = (statbuf.st_mode & S_IRGRP) ? 'r':'-';
perms[5] = (statbuf.st_mode & S_IWGRP) ? 'w':'-';
perms[6] = (statbuf.st_mode & S_IXGRP) ? 'x':'-';
//其他人
perms[7] = (statbuf.st_mode & S_IROTH) ? 'r':'-';
perms[8] = (statbuf.st_mode & S_IWOTH) ? 'w':'-';
perms[9] = (statbuf.st_mode & S_IXOTH) ? 'x':'-';
//获取硬连接数
int linkNum = statbuf.st_nlink;
//文件所有者
char *fileUser = getpwuid(statbuf.st_uid)->pw_name;
//文件所在组
char * fileGrep = getgrgid(statbuf.st_gid)->gr_name;
//文件大小
long int fileSize = statbuf.st_size;
//获取修改时间
char *fileTime = ctime(&statbuf.st_mtime); //将时间转换为当前时间
char mtime[512] = {0};
strncpy(mtime,fileTime,strlen(fileTime)-1);
char buf[1024];
sprintf(buf,"%s %d %s %s %ld %s %s",perms,linkNum,fileUser,fileGrep,fileSize,mtime,argv[1]);
printf("%s\n",buf);
return 0;
}