文件编程 Linux C--文件I/O编程

嵌入式Linux C概述

c和Linux c区别(嵌入式和非嵌入式区别):是否有操作系统

操作系统:
文件管理
设备管理
进程管理
网络协议栈

为什么要分为内核空间和用户空间?
由于在Linux中,为了更好的保护内核空间,将程序的运行空间分为内核空间和用户空间,用户进程在通常情况下不允许访问内核数据,也无法使用内核函数。

用户如何访问内核空间?
系统调用 硬件中断(没讲)

系统调用:
是指系统提供给用户的一组特殊接口(函数),用户可以通过这组特殊接口来获得操作系统内核提供的服务
它并不是直接与程序员进行交互的,在实际使用中程序员调用的是用户编程接口—API

怎么进行系统调用?
用户编程接口(函数接口)—API

系统命令和系统调用API的关系
在这里插入图片描述

为什么要学习嵌入式Linux C开发?
1、嵌入式上层应用软件开发
2、嵌入式底层软件的测试程序

嵌入式Linux C开发-I/O技术

嵌入式Linux系统中文件作用:“一点哲学”—一切皆为文件,通过文件来管理比较方便(文件系统)

Linux文件类型分类:
-表示普通文件;
d表示目录文件;
l表示链接文件;
c表示字符设备;
b表示块设备;
p表示管道文件,如FIFO文件;
f表示堆栈文件,如LIFO。

文件描述符:
知道一个文件的id,操作这个id,就相当与操作这个文件

动态分配:只要当操作这个文件时,系统才会给你分配文件描述符
非负整数:从3编号开始
0,1,2三个文件描述符有其它作用
在这里插入图片描述
无缓冲访问文件(系统调用)

creat函数:

//mode_t 无符号整数

作用:创建文件
请添加图片描述
第一个参数:创建的文件名,可带路径
第二个:权限

成功返回一个文件描述符,失败返回-1

注意:如果已经存在会被覆盖

errno:用来保存系统调用的错误信息,文件编程
perror:可以直接打印错误信息请添加图片描述

open函数:

在这里插入图片描述

第一个参数:文件名
第二个参数:指定打开的方式

O_RDONLY:只读
O_WRONLY:只写
O_RDWR:可读可写
上面三种之间互斥,可以用 | 与下列一起使用
O_CREAT:不存在就创建
O_APPEND:读写文件时从文件尾开始移动,所写数据会加入到文件后面

第三个参数:创建文件时使用,指定权限

write函数

在这里插入图片描述
第一个参数:函数描述符,写入的文件
第二个参数:数据存放缓冲区的地址
第三个参数:写多少个

写入成功,返回写入的个数,不成功,返回小于0的数

O_APPEND:从末尾添加

read函数:

请添加图片描述
第二个参数,读出来的参数放入的地址

返回值:成功返回读到的字节数
==0 ,读到文件尾
-1,有错误发生

lseek函数:

作用:移动文件读写位置指针
请添加图片描述
第二个参数:有符号 正,往后移 负,往前移
第三个参数:请添加图片描述
第一个,相对于文件头
第二个,当前位置
第三个,末尾

返回距离头的位置

问题:如何用lseek获取文件的长度?
答:int file_len=lseek(fd,0,SEEK_END);

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>
#include<unistd.h>

int main(int argc,char* argv[])
{
 	int fd=open(argv[1],O_RDWR|O_CREAT,0655);
	if(fd==-1)
	{
		perror("open file error!");
		exit(1);
	}
	printf("open file success=%d\n",fd);

	char buffer[1024];
	strcpy(buffer,"hello world");
	
       int w_len=write(fd,buffer,strlen(buffer));

       if(w_len==-1)
       {
	       perror("write data error!");
	       exit(1);
       }
       printf("write data len=%d\n",w_len);

       lseek(fd,0,SEEK_SET);
       //lseek(fd,-w_len,SEEK_CUR);
       memset(buffer,0,sizeof(buffer));//清空缓冲区

      int r_len=read(fd,buffer,sizeof(buffer)-1);

      if(r_len==-1)//==0 读到了末尾
      {
	      perror("read data error!");
	      exit(1);
      }
      else if(r_len==0)
      {
	      printf("read file end!\n");
      }

      buffer[r_len]='\0';

      printf("read data:%s\n",buffer);

	close(fd);
	return 0;
}

实例1:
写三行数据hello1、hello2、hello3
分别读出每行数据

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<unistd.h>

int read_line(int fd,char*buffer,int max_len)
{
	int i;
	int ret;
	char temp;

	for(i=0;i<max_len;i++)
	{
		ret=read(fd,&temp,1);
		if(ret<0)
		{
			perror("read error!");
			exit(1);
		}
		if(ret==0)
		{
			break;
		}
		
		if(temp=='\n')
		{
			break;
		}
		buffer[i]=temp;
	}
	buffer[i]='\0';

	return i;
}

int main(int argc,char*argv[])
{


	int fd;
	if((fd=open(argv[1],O_RDWR|O_CREAT,0655))==-1)
	{
		perror("open file errror!");
		exit(1);
	}
	char buffer[1024];

	for(int i=0;i<3;i++)
	{
		memset(buffer,0,sizeof(buffer));
		printf("please input data:\n");
		scanf("%s",buffer);

		if(write(fd,buffer,strlen(buffer))<0)
		{
			perror("write data error!");
			exit(1);
		}
		write(fd,"\n",1);
	}

	memset(buffer,0,sizeof(buffer));
	lseek(fd,0,SEEK_SET);

	while(read_line(fd,buffer,sizeof(buffer)-1)!=0)
	{
		printf("buffer=%s\n",buffer);
		memset(buffer,0,sizeof(buffer));
	}

	close(fd);

	return 0;
}

请添加图片描述
实例2:拷贝文件

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<unistd.h>

#define BUFFER_SIZE 1024

int main(int argc,char *argv[])
{
	int from_fd,to_fd;
	int bytes_read,bytes_write;
	char buffer[BUFFER_SIZE];
	char *ptr;

	if(argc!=3)
	{
		perror("fail!");
		exit(1);
	}
	//打开源文件
	if((from_fd=open(argv[1],O_RDONLY))==-1)
	{
		perror("open fail!");
		exit(1);
	}
	//创建文件
	if((to_fd=open(argv[2],O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR))==-1)
	{
		perror("open fail");
		exit(1);
	}
	while(bytes_read=read(from_fd,buffer,BUFFER_SIZE))
	{
		if((bytes_read==-1)&&(errno!=EINTR))
			break;
		else if(bytes_read>0)
		{
			ptr=buffer;
			while(bytes_write=write(to_fd,ptr,bytes_read))
			{
				if((bytes_write==-1)&&(errno!=EINTR))
					break;
				else if(bytes_write==bytes_read)
					break;
				else if(bytes_write>0)
				{
					ptr +=bytes_write;
					bytes_read-=bytes_write;
				}
			}
			if(bytes_write==-1)
				break;
		}
	}
	close(from_fd);
	close(to_fd);
	exit(0);
}

请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

&*Savior

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值