文章目录
常见的API
API
打开open
读写read write
光标定位 lseek
关闭 close
fd,即file descriptor,文件描述符。linux下,所有的操作都是对文件进行操作,而对文件的操作是利用文件描述符(file descriptor)来实现的。非负整数。
//通过man手册查看API原型
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
ssize_t write(int fd, const void *buf, size_t count);
ssize_t read(int fd, void *buf, size_t count);
off_t lseek(int fd, off_t offset, int whence);//fd,偏移值(正负),位置
Pathname:要打开的文件名(含路径,缺省为当前路径)
Flag:
O_RDONLY只读打开
O_WRONLY只写打开
O_RDWR 可读可写打开
当我们附带了权限后,打开的文件就只能按照这种权限来操作。以上这三个常数中应当只指定一 个。
下列常数是可选择的:
O_CREAT 若文件不存在则创建它。使用此选项时,需要同时说明第三个参mode,用其说明该新文件的存取许可权限。
O_EXCL 如果同时指定了OCREAT,而文件已经存在,则出错。
O_APPEND 每次写时都加到文件的尾端。
O_TRUNC 属性去打开文件时,如果这个文件中本来是有内容的,而且为只读或只写成功打开,则将其长度截短为0。
lseek
SEEK_SET 文件的头位置
SEEK_CUR 文件的当前位置
SEEK_END 文件的尾位置
补充:return lseek计算文件内容大小 size= lseek(fd,0,SEEK_END);
综合demo
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
int main()
{
int fd;
char *writebuf="hello world!";
fd=open("./file1",O_RDWR);
if(fd==-1){
printf("open file failed\n");
fd=open("./file1",O_RDWR|O_CREAT,0600);
if(fd>0){
printf("create file1 success\n");
}
}
fd=open("./file1",O_RDWR);
//ssize_t write(int fd, const void *buf, size_t count);
int n_write =write(fd,writebuf,strlen(writebuf));
if(n_write !=-1){
printf("write %d byte to file\n",n_write);
}
//close(fd);
//fd=open("./file1",O_RDWR);
//off_t lseek(int fd, off_t offset, int whence);
char *readBuf;
readBuf =(char *)malloc(sizeof(char)*n_write +1);
//ssize_t read(int fd, void *buf, size_t count);
lseek(fd,0,SEEK_SET);
int n_read =read(fd,readBuf,n_write);
printf("read %d,context:%s\n",n_read,readBuf);
close(fd);
return 0;
}
文件描述符标准输入0、标准输出1、标准错误2
按照惯例,UNIXshell使用文件描述符0与进程的标准输入相结合,文件描述符1与标准输出相结合,文件描述符2与标准错误输出相结合。STDINLFILENO、STDOUT
LFILENO STDERR_ FI LENO这几个宏代替了0、1、2这几个魔数。通常标准输入流对应着键盘的设备文件、标准输出流和错误流对应着显示器的设备文件。
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
int main()
{
int fd;
char readBuf[128];
int n_read =read(0,readBuf,5);
int n_write = write(1,readBuf,strlen(readBuf));
printf("done!\n");
return 0;
}
实现Linux cp命令代码
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc,char **argv)
{
int fdSrc;
int fdDes;
char *readBuf=NULL;
if(argc !=3){
printf("error\n");
exit(-1);
}
fdSrc = open(argv[1],O_RDWR);
int size= lseek(fdSrc,0,SEEK_END);
lseek(fdSrc,0,SEEK_SET);
readBuf=(char *)malloc(sizeof(char)*size +8);
int n_read = read(fdSrc,readBuf,size);
fdDes = open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0600);
int n_write=write(fdDes,readBuf,strlen(readBuf));
close(fdSrc);
close(fdDes);
return 0;
}
Linux配置文件的修改
test.config:
SPEED=3
LENG=3
SCORE=9
LEVEL=5
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc,char **argv)
{
int fdSrc;
char *readBuf=NULL;
if(argc !=2){
printf("error\n");
exit(-1);
}
fdSrc = open(argv[1],O_RDWR);
int size= lseek(fdSrc,0,SEEK_END);
lseek(fdSrc,0,SEEK_SET);
readBuf=(char *)malloc(sizeof(char)*size +8);
int n_read = read(fdSrc,readBuf,size);
char *p=strstr(readBuf,"LENG=");
if(p==NULL){
printf("not found\n");
exit(-1);
}
p=p+strlen("LENG=");
*p='5';
lseek(fdSrc,0,SEEK_SET);
int n_write =write(fdSrc,readBuf,strlen(readBuf));
close(fdSrc);
return 0;
}
写一个数字到文件
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main() {
int fd;
int data=100;
int data2=0;
fd =open("./file1",O_RDWR);
int n_write=write(fd,&data,sizeof(int));
lseek(fd,0,SEEK_SET);
int n_read=read(fd,&data2,sizeof(int));
printf("read %d\n",data2);
close(fd);
return 0; }
写一个结构体到文件
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
struct Test
{
int a;
char c;
};
int main()
{
int fd;
struct Test data[2]={{100,'a'},{101,'b'}};
struct Test data2[2];
fd=open("./file1",O_RDWR);
int n_write=write(fd,&data,sizeof(struct Test)*2);
lseek(fd,0,SEEK_SET);
int n_read=read(fd,&data2,sizeof(struct Test)*2);
printf("read %d,%c\n",data2[0].a,data2[0].c);
printf("read %d,%c\n",data2[1].a,data2[1].c);
close(fd);
return 0;
}
open fopen的区别
1、来源
open是Unix系统调用函数,返回的是文件描述符(fd),它是文件在文件描述符表里的索引。
fopen是ANSIC标准中的C语言库函数,在不同系统中应调用不同的内核api,返回的是一个指向文件结构的指针。
2、移植性
fopen是C标准函数,有良好的移植性。open是Unix系统调用,移植性有限。
3、使用范围
open返回文件描述符,而文件描述符是unnix系统下的重要概念,unix下的一切设备都是文件的形式操作,如网络套接字、硬件设备等、当然包括操作普通正规文件(Regular File)
Fopen是从来操纵普通正规文件(Regular File)的
4、 文件IO层次
如果从文件IO的角度来看,open属于低级IO函数,fopen属于高级IO函数,低级和高级的简单区分标准是:谁离系统内核更近,低级文件IO运行在内核态、高级文件IO运行在用户态。
5、 缓冲区
open没缓冲区,fopen有缓冲区
fopen
FILE *fopen(const char *path, const char *mode);
FILE *fdopen(int fd, const char *mode);
FILE *freopen(const char *path, const char *mode, FILE *stream);
mode打开模式:
r 只读方式打开一个文本文件
rb 只读方式打开一个二进制文件
w 只写方式打开一个文本文件
wb 只写方式打开一个二进制文件
a 追加方式打开一个文本文件
ab 追加方式打开一个二进制文件
r+ 可读可写方式打开一个文本文档
rb+ 可读可写打开一个二进制文件
w+ 可读可写创建一个文本文件
wb+ 可读可写方式生成一个二进制文件
a+ 可读可写追加方式打开一个文本文件
ab+ 可读可写追加方式打开一个二进制文件
fread fwrite fseek
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
int fseek(FILE *stream, long offset, int whence);
综合demo2
#include<stdio.h>
#include<string.h>
int main()
{
FILE *fp;
char *str ="hello world\n";
char readBuf[128]={0};
//FILE *fopen(const char *path, const char *mode);
fp=fopen("./file.txt","w+");
//size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
fwrite(str,sizeof(char),strlen(str),fp);
// int fseek(FILE *stream, long offset, int whence);
fseek(fp,0,SEEK_SET);
//size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
fread(readBuf,sizeof(char),strlen(str),fp);
printf("read:%s",readBuf);
fclose(fp)
return 0;
}
标准c库写入结构体
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Test
{
int a;
char c;
};
int main()
{
FILE *fp;
struct Test data = {100,'a'};
struct Test data2;
fp=fopen("./file","w+");
int n_write = fwrite(&data,sizeof(struct Test),1,fp);
fseek(fp,0,SEEK_SET);
int n_read = fread(&data2,sizeof(struct Test),1,fp);
printf("read:%d,%c\n",data.a,data.c);
fclose(fp);
return 0;
}
fgetc fputc feof
int fputc(int c, FILE *stream);
int fgetc(FILE *stream);
int feof(FILE *stream);//判断是否到达文件尾巴,到了为0
#include <stdio.h>
#include <string.h>
int main()
{
FILE *fp;
char c;
fp = fopen("file.txt","r+");
while(!feof(fp)){
c = fgetc(fp); //读出一个字符
printf("%c",c);
}
fclose(fp);
return 0;
}