Linux下文件I/O
"一切皆文件"是 Unix/Linux 的基本哲学之一。不仅普通的文件,目录、字符设备、块设备、 套接字等在 Unix/Linux 中都是以文件被对待;它们虽然类型不同,但是对其提供的却是同一套操作界面。Linux有7中类型文件:普通文件-、目录(dierectory)文件、符号(link)链接、字符(character) 设备文件、块(block)设备文件、管道(pipe)文件、套接字(socket)文件。其中文件、目录、符号链接会占用磁盘空间来存储,而 块设备、字符设备、套接字、管道是伪文件,并不占用磁盘空间。
文件描述符
(file descriptor, fd)是Linux为了高效管理打开的文件创建的索引。程序在开始运行时,系统会自动打开三个文件描述符,0是标准输入,1是标准输出,2是标准错误。
文件I/O操作函数
读写文件中的内容一般为三步:打开(open())->读(read())->写(write())->关闭(close())。如果文件不存在可用creat()系统创建
creat()
int creat(const char *pathname, mode_t mode);
此函数用来创建一个新文件并返回其fd。它等价于 open(path, O_WRONLY|O_CREAT|O_TRUNC, mode);
open()
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
open()系统调用用来打开指定路径下的一个文件,并返回一个文件描述符(file description), 并且该文件描述符是当前进程最小、未使用的文件描述符数值。 flags指定打开模式,当flags = O_CREAT(创建一个文件并打开 )时,第三个参数指定创建文件的权限模式
creat()和open()详细链接
read()
ssize_t read(int fd, void *buf, size_t count);
read()函数用来从打开的文件描述符对应的文件中读取数据放到buf指向的内存空间中去,最多不要超过count个字节,这里的 count一般是buf剩余的空间大小。如read成功,则返回实际读到的字节数(由nbytes或读到文件尾决定,其中EOF宏用来判断 是否到了文件尾),如果返回值小于0则表示出错,如尝试读一个没有权限读的文件时就会抛错。 若buf中数据无法一次性读完,那么第二次读buf中数据时,其读位置指针(也就是第二个参数buf)不会自动移动,需要程序员来控制,而不是简单的将buf首地址填入第二参数即可。如可按如下格式实现读位置移动:write(fp, p1+len, (strlen(p1)-len)。
write()
ssize_t write(int fd, const void *buf, size_t count);
write()函数用来往打开的文件描述符fd指向的文件中写入buf指向的数据,其中count指定要写入的数据大小。如果返回值<0则 说明写入出错,譬如尝试往一个只读的文件中写入则会抛错,错误的原因系统会保存到errno变量中去。如果>0则为实际写入的 数据大小。
read()和write()详解链接
close()
int close(int fd);
该函数用来关闭一个打开的文件描述符,直接传入要关闭的fd,关闭一个文件时还会释放该进程加在该文件上的所有记录锁。当一个进程终止时,内核 将会自动关闭它所有打开的文件。
Linux下文件夹操作函数
DIR *opendir(const char *path)参数path指向目录流的下个目录进入点,将信息保存到struct dirent结构体中。
下面的这段代码是从树莓派的文件中读取传感器采集到温度,路径为 /sys/bus/w1/devices/28-xxxx/w1_slave
第一步:要读取 /sys/bus/w1/devices/28-xxxx/w1_slave 下的内容,就需要确定这个绝对路径。然而由于devices/28-xxxx这个是根据具体芯片型号而定,但是以28-开头。所以就先需要找到这个文件夹,用opendir()打开并在返回的结构体.d_name 中搜素那个文件夹
第二步:打开open()打开,read读取内容,read()会将读到的内容放入传入的buf中。
第三步:用strstr()在buf中找到温度的位置,由于在文件中找到的内容是字符串,需要用atof()转换成浮点数。最后关闭文件
float get_parameter()
{
char path1[50]= "/sys/bus/w1/devices/";/* get DS18B20 path: /sys/bus/w1/devices/28-xxxx/w1_slave */
char path2[10]="/w1_slave";
char buff[256];
DIR *dirp;
int fd=-1;
int rv=-1;
char *ptr;
char temparr[20];
float wendu;
struct dirent * p_dirrent;/*d_name(文件名)和d_type(文件类型),%d显示的值4代表目录,8代表文件*/
if((dirp=opendir(path1)