3-4 read/write,lseek函数,cp指令的代码实现

本文详细介绍了文件输入输出操作中的write、read及lseek函数的使用方法,并通过一个简单的文件复制示例展示了这些函数的实际应用。

1. write

 write(intfd, void *buf, size_t count ):

第一个参数:向哪一个文件中去写;第二个参数:向这个文件中写什么内容;第三个参数:向这个文件中写多少个。

返回值:是实际写的字节数。


2. read

read(intfd, void *buf, size_t count)

第一个参数:从哪一个文件中去读;第二个参数:读到什么地方去;第三个参数:读多少个。

返回值:是实际读的字节数


3. lseek

每个内核文件都有个文件读写位置指针,可以通过lseek函数调整这个位置。

 leek(intfd, off_t offset, int whence),该函数的头文件:sys/types.h  unistd.h;

功能:调整读写的位置指针;

第一个参数:要调整的文件的文件描述符;

第二个参数:偏移量,每一读写操作所需要移动的距离,单位是字节的数量,可正可负(向前移,向后移);

第三个参数:当前位置的基点,有三个标志,

   SEEK_SET:当前位置为文件的开头,新位置为偏移量的大小;

SEEK_CUR:当前位置为文件指针的位置,新位置为当前位置加上偏移量。

SEEK_END:当前位置为文件的结尾,新位置为文件的大小加上偏移量的大小。函

           数的

 

返回值:成功:文件当前的位置,出错:-1。


4. 示例,简单实现cp命令,拷贝文件

#include "stdio.h"
#include "unistd.h"
#include "fcntl.h"
#include "string.h"

int main(int argc,char *argv[]){
	int rd_fd,wr_fd;
	char read_buf[128] = {0};
	int rd_ret = 0;
	
	if(argc < 3){
		printf("Please input src file and dst file \n");
		return -1;
	}
	
	rd_fd = open(argv[1],O_RDONLY);
	if(rd_fd < 0){
		printf("open src file %s error\n",argv[1]);
		return -2;
	}
	printf("open src file %s success, rd_fd = %d\n",argv[1],rd_fd);
	
	wr_fd = open(argv[2],O_WRONLY);
	if(wr_fd < 0){
		printf("open dst file %s error\n",argv[2]);
		return -3;
	}
	printf("open dst file %s success, wr_fd = %d\n",argv[2],wr_fd);
	
	while(1){
		rd_ret = read(rd_fd,read_buf,128);
		if(rd_ret < 128){
			break;
		}
		write(wr_fd,read_buf,rd_ret);
		memset(read_buf,0,128);
	}
	write(wr_fd,read_buf,rd_ret);
	
	close(rd_fd);
	close(wr_fd);

	return 0;
}

#include <my_head.h> //计算源文件长度 创建目标文件并清空 int file(char const * src_file, char const * dest_file){ //打开源文件计算计算长度 int fd = 0; if(-1 == (fd = open(src_file, O_RDONLY))) return -1; int lenth = lseek(fd, 0, SEEK_END); close(fd); //创建目标文件 并 清空 if(-1 == (fd = open(dest_file, O_WRONLY | O_TRUNC | O_CREAT , 0666))) return -1; close(fd); return lenth; } int cp_file(char const * src_file, char const * dest_file, int offset, int cp_len){ //打开文件 int src_fd = 0; if(-1 == (src_fd = open(src_file, O_RDONLY))) return -1; int dest_fd = 0; if(-1 == (dest_fd = open(dest_file, O_WRONLY))) return -1; //定位光标 lseek(src_fd, offset, SEEK_SET); lseek(dest_fd, offset, SEEK_SET); //开始拷贝 char buff[10]; //拷贝存放的内容 int nbyte = 0; //读到字节数 int count = 0; //记录已经拷贝的字节数 while(1){ nbyte = read(src_fd, buff, sizeof(buff)); count += nbyte; // if(count < cp_len){ // write(dest_fd, buff, nbyte); // }else{ // // 100 120 30 // write(dest_fd, buff, cp_len- (count - nbyte)); // break; // } if(count >= cp_len){ write(dest_fd, buff, cp_len- (count - nbyte)); break; } write(dest_fd, buff, nbyte); } close(src_fd); close(dest_fd); return 0; } int main(int argc, char const *argv[]) { if(argc != 3) exit(-1); int lenth = file(argv[1], argv[2]); pid_t pid = 0; if(-1 == (pid = fork())){ return -1; }else if(pid > 0){ //父 cp_file(argv[1], argv[2], 0, lenth/2); }else if(pid == 0){ //子 cp_file(argv[1], argv[2], lenth/2, lenth-lenth/2); } return 0; } 根据这个代码的算法思路 仅仅是将进程改为线程 其他的都不用变
最新发布
08-09
一、文件io函数 1、readwrite 练习:编写实现cp 命令功能 用文件io实现 cp 源文件 新文件 2、lseek 二、库 1、什么是库文件 库就是一个二进制文件,是将.c文件编译生成的二进制文件, 里面存放的就是函数实现的二进制的机器指令,库又分为静态库和动态库 windows: 静态库:xxx.lib 动态库:xxx.dll linux: 静态库:libxxx.a 动态库:libxxx.so 2、静态库 1、静态库的概念 静态库是以 libxxx.a 格式命名的 lib 是前缀 .a 是后缀 xxx 是库名 如果在编译时使用的是静态库,会将静态库中的机器指令编译到可执行文件中, 可执行文件的体积相对较大,执行效率相对较高。 静态库更新操作比较麻烦,需要重新编译生成可执行文件,否则拿不到新的库里的指令 2、静态库的制作 3、静态库的制作流程 1、将源文件编译生成目标文件 gcc -c hqyj.c -o hqyj.o 2、 创建动态库用指定命令制作静态库 ar -cr libhqyj.a hqyj.o 3、测试静态库 -I(大写的i)指定头文件的路径 -L指定库的路径 -l(小写的L)指定的库名 gcc main.c -I ./ -L ./ -lhqyj -o test 或 gcc main.c -L ./ -lhqyj 3、动态库 动态库又叫共享库,是以 libxxx.so 命名的 lib 是前缀 .so 是后缀 xxx 是库名 如果在编译时使用的是动态库,只会将动态库中的函数符号表编译到可执行文件中, 可执行文件的体积相对较小,执行时需要去动态库中找到对应的机器指令执行,效率相对较低。 动态库更新操作非常方便,只需要替换库即可,执行时自动就执行了新的库里的指令 1、动态库的制作 2、静态库的制作流程 3、动态库的执行 gcc main.c -L ./ -lhqyj 4、报错处理 指定库的路径的方式: 方式1: 通过修改环境变量来指定库的路径---- (终端关闭,环境变量就没在了) 方式2: 将自己的动态库 放在系统默认的库的路径下---- 方式3: 通过修改系统的配置文件来实现----需要sudo权限 首先在自己库里面寻找,找不到的时候会到默认库里面找 然后执行 sudo ldconfig 重新加载配置 三、进程 https://hqyj.yuque.com/wrxu0u/gl61gy/bhklwevmw09s0il0?singleDoc# 《工厂图解-进程线程》 1、进程和程序的区别: 程序:编译好的可执行文件,程序在磁盘上存储的 程序是静态的,没有生命的周期的概念 进程:程序的一次执行过程就会创建一个进程 ·进程是动态的,有生命周期的 执行一个程序所分配的资源的总称 2、进程的特点 系统会为每个进程分配0-4g的空间,其中0-3g是用户空间,每个进程独有;3g-4g是内核空间,所有进程共享。 3、时间片轮转,上下文切换 4、linux进程包含了三个段: 在数据段把内存分配里面: 数据段:包括全局变量,常数,动态分配的空间(如malloc函数取得的空间)等; 代码段:存放的是程序中的代码 堆栈段:存放函数的返回地址,函数的参数,以及程序的局部变量 5、进程的种类 1、交互进程:这种进程维护一个终端,通过这个终端用户可以和进程进行交互。 例如:文本编辑 , qq 2、批处理进程:这种进程优先级比较低,运行的时候会被放到一个运行的队列中。 随着队列的执行,而逐渐执行。 例如gcc编译程序的时候这个进程就是批处理进程。 3、守护进程:守护进程就是后台运行的服务,随着系统的启动而启动,随着系统的终止而终止。 例如:windows 各种服务、默认的防火墙、火绒、 6、进程相关的命令 7、进程的状态 C 运行代码 复制代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 进程的状态: D 不可被中断的休眠态 I 空闲内核线程 R 运行态或者可被运行的状态(等待调度就能执行的状态) S 可中断的休眠态(可被kill信号中断)例如:sleep 休眠,不占用cpu T 停止态:当进程收到信号SIGSTOP时就会进入暂停状态。可向其发送SIGCONT信号让进程转换到可运行状态。 X 死亡态:进程结束了,永远不会被看到 Z 僵尸态:进程已经终止运行,但还占用系统资源 进程的附加状态: < 高优先级的进程 N 低优先级的进程 L 在内存区锁定(这个进程的内存区的东西不能被交换,咱们用不到这个了解就行) s 会话组组长 l 进程中包含多线程 + 前台进程组的进程 //ps -aux//查看全部的 ps -aux :其中的 a表示所有关联到终端的进程, 如果同时使用 x 则代表所有进程;u 表示列出进程的用户。   ps -elf : 其中-e 代表列出所有进程,-l 代表长格式,-f 代表完整的格式 8、进程的切换 就绪状态: 当进程已分配到除CPU以外的所有必要的资源,只要获得处理机便可立即执行,这时的进程状态称为就绪状态。 执行状态: 当进程已获得处理机(CPU),其程序正在处理机上执行,此时的进程状态称为执行状态。 阻塞状态: 正在执行的进程,由于等待某个事件发生而无法执行时,便放弃处理机而处于阻塞状态。 例如,等待I/O完成、申请缓冲区不能满足、等待信件(信号)等。 提取关键信息 生成思维导图
08-07
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值