linux文件io

本文详细介绍了Linux系统中对文件进行打开(open),创建(creat),写入(write),读取(read)以及使用ioctl进行设备控制的基本函数用法,并通过示例代码展示了如何操作设备文件如LED和ADC。同时提到了main函数的参数传递和错误处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于4412

1、open 打开操作

• Linux下一切皆文件

• 打开文件open函数
• int open(const char *path, int oflags);
• int open(const char *path, int oflags,mode_t mode);
– 参数path表示:路径名或者文件名。路径名为绝对路径名。
– 参数oflags表示:打开文件所采取的动作
O_RDONLY 文件只读; O_WRONLY 文件只写; O_RDWR文件可读可写;
O_NOCTTY 如果路径指向终端,则不将设备作为此进程的控制终端
O_NDELAY 非阻塞方式操作文件
– mode表示:设置创建文件的权限。权限的宏定义很麻烦,可以直接用数字替代
– 返回值:出错返回-1;否则返回文件句柄

open.c

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

main(){
	int fd;
	char *leds = "/dev/leds";
	char *test1 = "/bin/test1";
	char *test2 = "/bin/test2";
	
	if((fd = open(leds,O_RDWR|O_NOCTTY|O_NDELAY))<0){
		printf("open %s failed!\n",leds);
	}
		printf("\n%s fd is %d\n",leds,fd);
		
	if((fd = open(test1,O_RDWR,0777))<0){
		printf("open %s failed!\n",test1);
	}
		printf("%s fd is %d\n",test1,fd);	
		
	if((fd = open(test2,O_RDWR|O_CREAT,0777))<0){
		printf("open %s failed!\n",test2);
	}
		printf("%s fd is %d\n",test2,fd);	
}

执行之后:

LEDS_CTL DEBUG:Device Opened Success!

LEDS_CTL DEBUG:Device Closed Success!

/dev/leds fd is 3

open /bin/test1 failed!

/bin/test1 fd is -1

/bin/test1 fd is 4

2、creat创建操作

• Linux下一切皆文件
• 打开文件creat函数:
• int creat(const char * pathname, mode_t mode);
– 参数path表示:路径名或者文件名。路径名为绝对路径名。
– 参数oflags表示:打开文件所采取的动作。
• O_RDONLY文件只读;O_WRONLY文件只写;O_RDWR文件可读可写

creat.c

//标准输入输出头文件
#include <stdio.h>

//文件操作函数头文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

main()
{
	int fd;
	//开发板中已经存在/dev/leds文件
	char *leds = "/dev/leds";
	//开发板中不存在的文件/bin/test1
	char *test1 = "/bin/test1";
	//开发板中不存在的文件/bin/test2
	char *test2 = "/bin/test2";
	//需要新建的文件/bin/test3
	char *test3 = "/bin/test3";
	
	//使用open函数打开文件
	if((fd = open(leds, O_RDWR|O_NOCTTY|O_NDELAY))<0){
		printf("open %s failed\n",leds); 
	}
		printf("%s fd is %d\n",leds,fd);
	//使用open函数打开不存在的文件,不添加O_CREAT标识符,会报错
	if((fd = open(test1, O_RDWR))<0){
		printf("open %s failed\n",test1); 
	}
	//打开文件创建文件,添加标志位O_CREAT表示不存在这个文件则创建文件
		if((fd = open(test2, O_RDWR|O_CREAT,0777))<0){
		printf("open %s failed\n",test2); 
	}
		printf("%s fd is %d\n",test2,fd);
	
	fd = creat(test3,0777);
	if(fd = -1){
		printf("%s fd is %d\n",test3,fd);
	}
	else{
		printf("create %s is succeed\n",test3);
	}
}

查看

ls /bin/test*

/bin/test1 /bin/test2

3、write写操作

• 关闭文件close函数:
• int close(int fd);
• 写文件write函数:
• ssize_t write(int fd, const void *buf, size_t count);
– 参数 fd 表示:使用open 函数打开文件之后返回的句柄。
– 参数 *buf 表示:写入的数据
– 参数 count 表示:最多写入字节数
– 返回值:出错-1,;其它数值表示实际写入的字节数

write.c

//标准输入输出头文件
#include <stdio.h>

//文件操作函数头文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

main()
{
	int fd;
	char *testwrite = "/bin/testwrite";
	ssize_t length_w;
	char buffer_write[] = "Hello Write Function!";

	if((fd = open(testwrite, O_RDWR|O_CREAT,0777))<0){
		printf("open %s failed\n",testwrite); 
	}
	
	//将buffer写入fd文件
	length_w = write(fd,buffer_write,strlen(buffer_write));
	if(length_w == -1)
	{
		perror("write");
	}
	else{
		printf("Write Function OK!\n");
	}
	close(fd);
}

Write Function OK!

4、read读操作

• 读文件read函数:
• ssize_t read(int fd,void buf,size_t len);
– 参数fd:使用open 函数打开文件之后返回的句柄
– 参数
buf:读出的数据保存的位置
– 参数len:每次最多读len 个字节
– 返回值:错误返回-1,执行成功返回实际读取值

read.c

//标准输入输出头文件
#include <stdio.h>

//文件操作函数头文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

#define MAX_SIZE 1000

main(){
	int fd;
	ssize_t length_w,length_r = MAX_SIZE,ret;
	char *testwrite = "/bin/testwrite";
	char buffer_write[] = "Hello Write Function!";
	char buffer_read[MAX_SIZE];
	// write
	if((fd = open(testwrite,O_RDWR|O_CREAT,0777))<0){
		printf("open %s failed!\n",testwrite);
	}
	length_w = write(fd,buffer_write,strlen(buffer_write));
	if(length_w == -1){
		perror("write");
	}
	else{
		printf("Write Function OK!\n");
	}
	close(fd);
	// read
	if((fd = open(testwrite,O_RDWR|O_CREAT,0777))<0){
		printf("open %s failed!\n",testwrite);
	}
	if(ret = read(fd,buffer_read,length_r)){
		perror("read");
	}
	printf("Files Content is %s \n",buffer_read);
	close(fd);
}

Write Function OK!

Files Content is Hello Write Function!

5、main函数传参

argv.c

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

//argument count变元计数
//argument value变元值
int main(int argc,char *argv[])
{
	int i,j;
	i = atoi(argv[1]);
	j = atoi(argv[2]);
	
	printf("the Program name is %s\n",argv[0]);
	
	printf("The command line has %d argument:\n",argc-1);
	
	printf("%d,%d\n",i,j);
	
	return 0;
}

6、ioctl函数

• ioctl函数:
• int ioctl( int fd, int request, int cmd);
– 参数fd,函数open 返回的句柄
– 参数 request 和参数 cmd,由内核驱动决定具体操作,例如 request 可以代表那个IO 口
– 参数 cmd:代表对IO 进行什么样的操作,也可以反过来。具体的含义由驱动工程师在驱动中switch决定
– 返回值:返回0 成功;返回-1,出错

leds.c

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

#define LED_NUM 2
#define LED_C 2
//cmd为0,则灭,为1,则亮;
//io为0则是靠近蜂鸣器的小灯,为1则靠近独立按键的小灯
int main(int argc,char *argv[])
{
	int fd,led_num,led_c;
	char *leds = "/dev/leds";

	led_num = LED_NUM;
	led_c = LED_C;
	
	printf("argv1 is cmd;argv2 is io \n"); 
	//对传入的参数进行判断,超出范围直接退出
	if (atoi(argv[1]) >= led_c) {
		printf("argv1 is 0 or 1)");
		exit(1);
	}
	if (atoi(argv[2]) >= led_num) {
		printf("argv2 is 0 or 1)");
		exit(1);
	}
	//使用ioctl函数将参数传入内核
	if((fd = open(leds, O_RDWR|O_NOCTTY|O_NDELAY))<0)
		printf("open %s failed\n",leds);   
	else{
			ioctl(fd,atoi(argv[1]),atoi(argv[2]));
			printf("ioctl %s success\n",leds);
		}
	close(fd);
	
	return(1);
}

buzzerTest.c

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

#define BUZZER_C 2
int main(int argc,char *argv[]){
	char *buzzer_ctl = "/dev/buzzer_ctl";
	int fd,ret,buzzer_c;
	
	buzzer_c = BUZZER_C;
	
	if(atoi(argv[1]) >= buzzer_c ){
		printf("argv[1] is 0 or 1\n");
		exit(1);
	}
	
	if((fd = open(buzzer_ctl,O_RDWR|O_NOCTTY|O_NDELAY))<0){
		printf("open %s failed\n",buzzer_ctl);
		exit(1);
	}
	
	ret = ioctl(fd,atoi(argv[1]),atoi(argv[2]));
	close(fd);
	
	return 0;
}

./test 0 1 不响

./test 1 1 响

7、使用文件I/O函数读取ADC的值

• 对ADC的控制需要文件IO的基础
• 数模转换需要read读函数
• AD寄存器ADCDAT最大为0XFFF,最小为0
• 电阻最大为10K,最小为0

ADC.c

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <stdint.h>
#include <termios.h>
//#include <android/log.h>
//#include <sys/ioctl.h>

int main(void){
	int fd;
	char *adc = "/dev/adc";
	char buffer[512];
	int len=0, r=0;
	
	memset(buffer,0,sizeof(buffer));
		printf("adc ready!\n");
	
	if((fd = open(adc, O_RDWR|O_NOCTTY|O_NDELAY))<0)
		printf("open adc err!\n");
	else{
		printf("open adc success!\n");
		
		len=read(fd,buffer,10);	
		
		if(len == 0)
			printf("return null\n");
		else{
			r = atoi(buffer);
			r = (int)(r*10000/4095);	//Datas  transition to Res
			printf("res value is %d\n",r);
		}			
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值