Linux文件

常见的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;
}



评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值