Linux 系统调用(system call)是指操作系统提供给用户程序的一组“特殊接口”,用户程序可以通过这组“特殊”接口来获得操作系统提供的特殊服务。
为了更好的保护内核空间,将程序的运行空间分为内核空间和用户空间,他们运行在不同的级别上,在逻辑上是相互隔离的。在 Linux 中,用户程序不能直接访问内核提供的服务,必须通过系统调用来使用内核提供的服务。
Linux 中的用户编程接口(API)遵循了 UNIX 中最流行的应用编程界面标准—— POSIX。这些系统调用编程接口主要是通过 C 库(libc)实现的。
往期传送门:
史上最全的Linux常用命令汇总(超详细!超全面)收藏这一篇就够了
Linux下标准IO的这些操作你清楚吗(内附有详细的介绍和例程)
注意:每个程序中打开的文件系统会单独分配文件描述符,互相不影响
标准I/O | 文件I/O |
---|---|
ANSIC | POSIX |
带缓冲(减少系统调用次数) | 无缓冲(读写文件需要进行系统调用 ) |
流(FILE结构体)打开文件 | 文件描述符 表示一个打开的文件 |
open函数用来创建或者打开一个文件:
#include
int open(const char *path,int oflag,...);
//参数1:打开文件路径 参数2:打开方式
int fd;
if((fd=open("1.txt",O_WRONLY|O_CREAT|O_TRUNC,0666))<0
{
perror("open");
return -1;
}
int fd;
if((fd=open("1.txt",O_RDWR|O_CREAT|O_EXCL,0666))<0)
{
if(errno==EEXIST)
{
perror("exist error");
}
else
{
perror("other error");
}
}
close函数用来关闭一个打开的文件:
#include
int close(int fd);
read函数用来从文件中读取数据:
#include
ssize_t read(int fd,void *buf,size_t count);
#include
#include
int main(int argc,char *argv[])
{
int fd,n,total=0;
char buff[64];
if(argc<2){
prinff("Usage:%s\n" ,argv[0];
return -1;
}
if((fd=open(argv[1],O_RDONLY))<0){
perror("open";
return -1;
}
while((n=read(fd,buf,64))>0){//读取64个字节到buf中并保存返回值到n
total+=n;//total的值即为文件的大小
}
printf("size:%d\n",total);
return 0;
}
write函数用来向文件写入数据:
#include
ssize_t write(int fd,void *buf,size_t count);//buf写入内容;count写入大小
#include
#include
#include
int main(int argc,char *argv[])
{
int fd;
char buf[20];
//只写方式打开文件,如果文件不存在创建,如果文件存在则清空
if((fd =open(argv[1],O_WRONLY|OCREAT|O_TRUNC,0666))<0{
perror("open");
return -1;
}
while(fgets(buf,20,stdin)!=NULL){
if(strcmp(buf,"quit\n")==0)break;
write(fd,buf,strlen(buf));
}
lseek函数用来定位文件:
#include
off_t lseek(int fd,off_t offset,intt whence);
opendir函数用来打开一个目录文件:
#include
DIR *opendir(const char *name);
readdir函数用来读取目录流中的内容:
#include
struct sirent *readdir(DIR *dirp);
char d_name[256]
等成员closedir用来关闭一个目录文件:
#include
int closedir(DIR *drip);
#include
#include
int main(int argc,char *argv[])
{
DIR *drip;
struct dirent *dp;
if(argc<2){
printf("Usage :%s\n" argc[0]);return -1;
}
if((dirp=opendir(argv[1]))==NULL){
perror("opendir");
return -1;
}
while((dp=readdir(dirp))!=NULL){
printf("%s\n",dp->d_name);
}
closedir(dirp);
return 0;
}
chmod/fchmod函数用来修改文件的访问权限:
#include
int chmod(const char *path,mode_t mode);
int fchmod(int fd,mode_t mode);
#include
int stat(const char *path,struct stat *buf);
int lstat(const char *path,struct stat *buf);
int fstat(int fd,struct stat *buf);
struct stat是存放文件属性的结构体类型:
结构体类型 | 作用 |
---|---|
mode_t st_mode | 类型和访问权限 |
uid_t st_uid | 所有者id |
uid_t st_gid | 用户id |
off_t st_size | 文件大小 |
time_t st_mtime | 最后修改时间 |
st_mode通过系统提供的宏来判断文件类型:
通过(st_mode&0170000)计算后得到的值和以下进行匹配
文件类型 | 计算值 |
---|---|
S_ISREG(st_mode) 普通文件 | 0100000 |
S_ISDIR(st_mode)目录文件 | 0040000 |
S_ISCHR(st_mode) | 0020000 |
S_ISBLK(st_mode) | 0060000 |
#include
#include
#include
#include
#include
int main(int argc,char *argv[])
{
struct stat buf;
struct tm *tp;//获取本地时间的指针
int n;
if(argc<2)
{
printf("Usage:%s \n" ,argv[0]);
return -1;
}
if(lstat(argv[1],&buf)<0)
{
perror("lstat");
return -1;
}
switch(buf.st_mode&S_IFMT)
{
case S_IFRGE:
printf("-");
break;
case S_IFDIR:
printf("d");//是一个目录文件
break;
}
for(n=8;n>=0;n--)
{
if(buf.st_mode&(1<<n))
{
switch(n%3)
{
case 2:
printf("r");
case 1:
printf("w");
break;
case 0:
printf("x");
break;
}
}
else
{
printf("-");
}
}
printf("%lu",buf.st_size);
tp=localtime(buf.st_mtime);//转换为本地时间
printf("%d-%02d-%02d",tp->tm_year+1900,tp->tm_mon+1,tp->tm_mday);//年月日 天数
printf("%s\n",argc[1]);
return 0;
}
不积小流无以成江河,不积跬步无以至千里。而我想要成为万里羊,就必须坚持学习来获取更多知识,用知识来改变命运,用博客见证成长,用行动证明我在努力。
如果我的博客对你有帮助、如果你喜欢我的博客内容,记得“点赞” “评论” “收藏”一键三连哦!听说点赞的人运气不会太差,每一天都会元气满满呦!如果实在要白嫖的话,那祝你开心每一天,欢迎常来我博客看看。