1、磁盘、Flash、SD卡、U盘
这些来源是真实存在的文件,以FAT32,EXT4,…等格式保存在某个设备上(如/dev/sda1),要使用mount
指令挂载才能使用。
df -T//文件系统类型在Type列输出。只可以查看已经挂载的分区和文件系统类型。
2、Linux内核提供的虚拟文件系统,使用时也需要mount
指令挂载才能使用。
3、特殊文件:/dev/下的文件,这些文件是一些设备结点,我们通过open、write操作它们时,通过驱动操作的是硬件。
主设备号用来确定哪一个驱动程序,次设备号用来确认哪一个硬件。
如:
一块开发板里IIC设备的主设备号都是89,但IIC1、IIC2的次设备号不同。
对于访问LInux文件有两种方法:1、通用的API访问。2、不通用的API访问
/*open*/
int open(const char *pathname,int flags);/*pathname:指向文件路径的指针;flags:文件权限*/
int open(const char *pathname,int flags,mode_t mode);/*pathname:指向文件路径的指针;flags:文件权限;mode:创建模式*/
/*成功:返回文件描述符*/
/*write*/
ssize_t write(int fd,const void *buf,size_f count);/*fd:文件描述符*/
/*成功:返回写入字节的个数(一个整型数)失败:返回-1;*/
/*read*/
ssize_t read(int fd,const void *buf,size_f count);/*fd:文件描述符;buf:接收的buf;count:读出了多少长度的字节*/
/*成功:返回读取字节的个数(一个整型数)失败:返回-1;*/
/*lseek*/
off_t lseek(int fd, off_t offset, int whence);/*fd:文件描述符;offset:对于whence的偏移值;whence:固定点位置*/
/*成功完成后,lseek()返回相应的偏移量从文件开始的字节数。利用这个特性可以计算文件的大小*/
/*close*/
int close(int fd);/*fd:文件描述符*/
/*返回值:成功返回0,出错返回-1并设置errno*/
API参数的详细解析:
Linux系统编程篇—文件编程(一)打开及创建、写入、读取
Linux系统编程篇—文件编程(二)光标移动(lseek)
ioctl(input/output control)是一个专用于设备输入输出操作的系统调用,该调用传入一个跟设备有关的请求码,系统调用的功能完全取决于请求码。举个例子,CD-ROM驱动程序可以弹出光驱,它就提供了一个对应的Ioctl请求码。设备无关的请求码则提供了内核调用权限。
ioctl是设备驱动程序中对设备的I/O通道进行管理的函数。所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率、马达的转速等等。
函数原型:
int ioctl(int fd, ind cmd, …);/*fd:文件标示符,cmd:用户程序对设备的控制命令;后面的省略号:那是一些补充参数,一般最多一个,这个参数的有无和cmd的意义相关。*/
函数说明:
① fd 表示文件描述符;
② request 表示与驱动程序交互的命令,用不同的命令控制驱动程序输出我们需要的数据;
③ … 表示可变参数 arg,根据 request 命令,设备驱动程序返回输出的数据。 ④ 返回值:打开成功返回文件描述符,失败将返回-1。
ioctl 的作用非常强大、灵活。不同的驱动程序内部会实现不同的 ioctl,APP 可以使用各种 ioctl 跟驱动程序交互:可以传数据给驱动程序,也可以从驱动程序中读出数据。
mmap将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零。mmap在用户空间映射调用系统中作用很大。
函数原型:
void* mmap(void* start,size_t length,int prot,int flags,int fd,off_t offset);
函数说明:
① addr 表示指定映射的內存起始地址,通常设为 NULL 表示让系统自动选定地址,并在成功映射后返回该
地址;
② length 表示将文件中多大的内容映射到内存中;
③ prot 表示映射区域的保护方式,可以为以下 4 种方式的组合
a. PROT_EXEC 映射区域可被执行
b. PROT_READ 映射区域可被读出
c. PROT_WRITE 映射区域可被写入
d. PROT_NONE 映射区域不能存取
④ Flags 表示影响映射区域的不同特性,常用的有以下两种
a. MAP_SHARED 表示对映射区域写入的数据会复制回文件内,原来的文件会改变。
b. MAP_PRIVATE 表示对映射区域的操作会产生一个映射文件的复制,对此区域的任何修改都不会写回 原来的文件内容中。
⑤ 返回值:若成功映射,将返回指向映射的区域的指针,失败将返回-1。
程序流程图:
(1)使用通用的 IO 模型(open/read/write/lseek/close)实现cp函数
#include
#include
#include
#include
#include
#include
int main(int argc,char **argv)
{
int old_fd=0;
int new_fd=0;
long int r_len=0;
long int w_len=0;
char buf[1024]={'\0'};
int cnt =1;
/*1、输入判断*/
if(argc!=3){
printf("input is error!\n");
printf("format:%s \n" ,argv[0]);
return -1;
}
/*2、打开老文件*/
old_fd=open(argv[1],O_RDONLY);
if(old_fd==-1){
printf("open %s failure\n",argv[1]);
return -1;
}
printf("open %s success\n",argv[1]);
/*3、打开新文件*/
new_fd=open(argv[2],O_WRONLY|O_CREAT,0600);
if(new_fd==-1){
printf("open %s failure\n",argv[2]);
return -1;
}
printf("open %s success\n",argv[2]);
/*4、写入数据*/
while((r_len=read(old_fd,buf,1024))>0){
printf("read success %d\n",cnt);
printf("read data %ld\n",r_len);
w_len=write(new_fd,buf,r_len);
if(w_len!=r_len){
printf("write data error !\n");
return -1;
}
printf("write success %d\n",cnt++);
printf("write data:%ld\n",w_len);
}
/*5、关闭文件*/
close(old_fd);
close(new_fd);
return 0;
}
(2)使用非通用的 IO 模型(ioctl/mmap)实现cp函数
#include
#include
#include
#include
#include
#include
#include
int main(int argc,char **argv)
{
int old_fd=0;
int new_fd=0;
long int r_len=0;
long int w_len=0;
char *buf;
struct stat stat;
/*1、判断参数*/
if(argc!=3){
printf("input is error!\n");
printf("format:%s \n" ,argv[0]);
return -1;
}
/*2、打开原文件*/
old_fd=open(argv[1],O_RDONLY);
if(old_fd==-1){
printf("open %s failure\n",argv[1]);
return -1;
}
/*3、确定老文件的大小*/
if(fstat(old_fd,&stat)==-1){
printf("can not get stat of file %s\n",argv[1]);
return -1;
}
printf("old file have %ld data\n",stat.st_size);
/*4、映射老文件*/
buf=mmap(NULL,stat.st_size,PROT_READ, MAP_SHARED,old_fd,0);
if(buf == MAP_FAILED){
printf("mmap fail\n");
return -1;
}
/*5、创建新文件*/
new_fd=open(argv[2],O_WRONLY|O_CREAT,0600);
if(new_fd==-1){
printf("open %s failure\n",argv[2]);
return -1;
}
printf("open %s success\n",argv[2]);
w_len=write(new_fd,buf,stat.st_size);
printf("write data:%ld\n",w_len);
close(old_fd);
close(new_fd);
return 0;
}
注:此处获取文件大小使用了一个fstat函数,详情参照:C语言用fstat函数获取文件的大小