linux文件操作(2)

七.文件操作原理

1.文件描述符
在这里插入图片描述
(1)文件描述符相当于文件的索引。
在linux中有三个默认的的文件描述符:

0标准输入
1标准输出
2标准错误

demo7

我们先从标准输入里面读取数据到readbuf里,然后再把readbuf里的数据标准输出。

#include<unistd.h>
#include<string.h>
#include<stdio.h>
int main()
{
	int fd;
	char readbuf[128];
	int n_read = read(0,readbuf,5);   //  0   Standard input
	int n_write = write(1,readbuf,strlen(readbuf));// 1 Standard output
	printf("\nDone\n");
	return 0;
}

(2)文件描述符的作用域就是当前进程,出了这个进程 文件描述符就没有意义了。
open函数打开文件,打开成功返回一个文件描述符,打开失败,返回-1.

2.在linux 打开/创建/读取/写入/关闭 文件
(1).在linux中要操作一个文件,一般是先open打开一个文件,得到文件描述符,然后对文件进行读写操作(或其他操作),最后是close关闭文件。
(2)文件读写完成后,一定要关闭文件,否则会造成文件损坏。
(3)静态文件和动态文件

静态文件动态文件
存放在磁盘中的文件(如桌面文件等)open静态文件后,会在Linux内核产生一个结构体(数据结构),来记录这个文件,内核在内存中申请一段内存,将静态文件的内容从块设备中读取到内核中特定地址管理存放。

在这里插入图片描述
(4)在这里插入图片描述
(5)为什么不直接对块设备直接操作?
答:块设备本身读写不灵活,是按块读写的,而内存是按字节单位操作的,而且可以随机操作,很灵活。

八.文件编程实例 (实现linux cp命令的代码)

demo_8_1.c
cp src.c des.c
c语言参数:

#include<stdio.h>
int main(int argc,char **argv)
{
	printf("total params:%d\n",argc);
	printf("NO1 params:%s\n",argv[0]);
	printf("NO2 params:%s\n",argv[1]);
	printf("NO3 params:%s\n",argv[2]);
	return 0;
	
}

运行结果:
在这里插入图片描述
demo8_2.c
思路:

  1. 打开src.c
  2. 读src到buf
  3. 打开/创建des.c
  4. 将buf写入到des.c
  5. close两个文件
#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 argc,char **argv)
{
	int fdSrc;
	int fdDes;
	char *readbuf = NULL;
	if(argc != 3)
	{
		printf("params error\n");  	 //params 参数
		exit(-1);
	}
	fdSrc = open(argv[1],O_RDWR);    	//打开src文件
	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);   //读取src文件内容,存储到readbuf中
	fdDes = open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0600);//打开Des文件
	int n_write = write(fdDes,readbuf,strlen(readbuf));//将readbuf里的内容写入到Des文件中

	close(fdSrc);
	close(fdDes);

	return 0;
}

注:O_TRUNC属性去打开文件时,如果这个文件中本来是由内容的,而且为只读或只写成功打开,则将其长度截短为0.

九.修改程序文件

1.先创建一个 .txt 文件。
在这里插入图片描述
demo9.c

  1. 先找到文件内容“LENG=”位置。
  2. 从该位置往后移动,移动到想要修改的地方。
  3. 修改该位置的内容。
#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 argc,char **argv)
{
	int fdSrc;
	char *readbuf = NULL;
	if(argc != 2)
	{
		printf("params error\n");  	 //params 参数
		exit(-1);
	}
	fdSrc = open(argv[1],O_RDWR);    	//打开src文件
	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);   //读取src文件内容,存储到readbuf中
	//char *strstr(const char *haystack, const char *needle);
	char *p = strstr(readbuf,"LENG=");
	if(p == NULL)
	{
		printf("No found\n");
		exit(-1);
	}
	p = p + strlen("LENG=");
	*p = '5';
	lseek(fdSrc,0,SEEK_SET);
	int n_write = write(fdSrc,readbuf,strlen(readbuf));//将readbuf里的内容写入到Des文件中

	close(fdSrc);

	return 0;
}

运行结果:
在这里插入图片描述

十. 写一个整数 ,结构体,数组到文件

1.写一个整数
demo10_1.c

#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 fdSrc;
	int data1=100;
	int data2;
	fdSrc = open("./file10",O_RDWR);    	//打开src文件
	int n_write = write(fdSrc,&data1,sizeof(int));//将readbuf里的内容写入到Des文件中
	lseek(fdSrc,0,SEEK_SET);
	int n_read = read(fdSrc,&data2,sizeof(int));
	printf("read:%d,context:%d\n",n_read,data2);

	close(fdSrc);

	return 0;
}

2.写一个结构体数组
demo10_2.c

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
struct Test
{
	int a;
	char b;
};
int main()
{
	int fdSrc;
	struct Test data1[2]={{100,'a'},{101,'b'}};
	struct Test data2[2];
	fdSrc = open("./file10",O_RDWR);    	//打开src文件
	int n_write = write(fdSrc,&data1,sizeof(struct Test)*2);//将readbuf里的内容写入到Des文件中
	lseek(fdSrc,0,SEEK_SET);
	int n_read = read(fdSrc,&data2,sizeof(struct Test)*2);
	printf("read:%d,%c\n",data2[0].a,data2[0].b);
	printf("read:%d,%c\n",data2[1].a,data2[1].b);

	close(fdSrc);

	return 0;
}

结果:
在这里插入图片描述

十一.标准c库对文件操作引入

fopen fread fwrite fseek fclose fgetc fputc feof

1.与之前的open等有什么区别?
参考:总结open与fopen的区别
在这里插入图片描述
2.相关API
在这里插入图片描述
(1)标准c库打开/创建/读写文件,光标移动
先看下下面这张图:
在这里插入图片描述
demo11_1.c

#include<stdio.h>

#include<string.h>

int main()

{

    FILE *fp;

    char *str = "FLG is very good!";

    char readbuf[128]={0};

    //FILE *fopen(const char *pathname, const char *mode);

    fp = fopen("./fan.txt","w+");

    //size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

    // ptr buf

    // size sizeof char

    // 个数 

    // which file

    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 data:%s\n",readbuf);

    fclose(fp);

}

demo11_2.c
c标准库写一个结构体到文件

#include<stdio.h>

#include<string.h>

struct test 
{
	int a;
	char b;
};
int main()

{

    FILE *fp;

    struct test data1[2]={{100,'a'},{101,'b'}};
    struct test data2[2];

    //FILE *fopen(const char *pathname, const char *mode);

    fp = fopen("./fan.txt","w+");

    //size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

    // ptr buf

    // size sizeof char

    // 个数 

    // which file

    fwrite(&data1, sizeof(struct test),1,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(&data2,sizeof(struct test),1,fp);

    printf("read data:%d,%c\n",data2[0].a,data2[0].b);
    printf("read data:%d,%c\n",data2[1].a,data2[1].b);

    fclose(fp);

}

(2)fgetc, fputc, feof 用法
(可通过man fputc 查看fputc的参数,用法)
_1.fputc

#include<stdio.h>
#include<string.h>
int main()
{
	FILE *fp;
	int i;
	char *str = "FLG is good!";
	fp = fopen("./text12.txt","w+");
	int len = strlen(str);
	//for(i=0;i<strlen(str);i++)
	for(i=0;i<len;i++)   //  str每循环一次,指向后一个字节,strlen(str)的长度会减小,所以这块用len提前记录最开始str的长度。
	{
		fputc(*str,fp);
		str++;
	}
	fclose(fp);
	return 0;
}

**_2.feof **
用来判断是否到达文件尾巴
若 到达文件尾巴,则返回非零,没有到达文件尾巴,返回0,
fgetc 文件输入
_2. feof fgetc

#include<stdio.h>
#include<string.h>
int main()
{
	FILE *fp;
	int i;
	char c;
	fp = fopen("./text12.txt","r");
	while(!feof(fp)){  // 没有到达文件尾巴,返回0, 再加上它的否定!,为非零,进入循环;
	//等最后一次循环结束后判断时,此时已经到达文件尾巴,返回非零,再取反,为0, 所以退出while
		c = fgetc(fp);
		printf("%c",c);
	}
	printf("\n");
	fclose(fp);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值