当前位置:文档之家› linux高级编程(文件操作)

linux高级编程(文件操作)

文件及设备操作1.基本概念linux下文件操作的两种方法:原始文件I/O、标准I/O库标准I/O库: 是C语言的标准输入输出库,是针对流对象FILE 进行的操作,是带缓存的。

原始I/O库:是linux系统提供的文件API,是针对描述描进行的操作,是无缓存机制。

文件描述符:创建一个新文件或打开现有文件时,内核向进程返回的一个非负整数。

其范围在0~OPENMAX之间,OPENMAX是一个宏,不同linux版本取值不同.系统调用:是操作系统提供的某些功能的接口(函数)常用设备/dev/null 空设备,丢弃数据用/dev/port 存取I/O端口/dev/ttyN N(0 1 ...) 字符终端/dev/sdaN N(0 1...) SCSI磁盘/dev/scdN N(0 1...) SCSI光驱/dev/mouseN N(0 1...) 鼠标/dev/socksys 套接字访问端口接口,用于网络传输/dev/route 路由器控制设备/dev/fbN N(0 1...) 帧缓冲设备(frame buffer) 重点/dev/mixer 混音器音量控制、混音控制重点/dev/dsp 声卡数字采样和数字录音设备用于播放声音和录音经常使用重点(oss)/dev/audio 声卡音频设备用于播放声音和录音,支持sun音频较少使用/dev/video 视频摄像头用于视频采样(录像)常用头文件#include <sys/types.h> 对外提供的各种数据类型如size_t#include <sys/stat.h> 对外提供的各种结构类型如time_t#include <errno.h> 对外提供的各种错误号的定义用数字代码的错误类型#include <fcntl.h> 文件控制的函数定义#include <termios.h> 串口的结构及定义#include <sys/soundcard.h> 声卡的结构及定义#include <sys/ioctl.h> 设备控制函数#include <unistd.h> 在C++内加入的头2.设备的操作函数#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/ioctl.h>#include <unistd.h>1)Access功能: 确定文件的访问权限用法: int access(const char *filename, int amode);finename 文件名称mode 模式,共5种模式:0-检查文件是否存在1-检查文件是否可运行2-检查文件是否可写访问4-检查文件是否可读访问6-检查文件是否可读/写访问例:判断文件是否存在int file_exists(char *filename){return (access(filename, 0) == 0);}2)创建文件int creat(char *pathname,mode_t mode);pathname:要创建文件的路径文件名。

可以使用绝对路径或相对路径。

mode: 新建文件的访问权限,同创建目录使用时,可用或运算组合使用,如S_IRUSR | SIWUSR写可以使用数字,如666返回值:成功,返回文件描述符,失败-1说明:3)打开文件int open(const char *pathname, int oflag,mode_t mode);pathname: 设备或文件名flags: 文件的打开方式,可以用位运算|组合O_RDONL Y 只读O_WRONL Y 只写O_RDWR 读写模式O_APPEND 追加模式O_CREAT 创建文件O_SYNC 同步。

O_NONBLOCK 非阻塞模式,默认为阻塞模式O_EXCL 如果定义了O_CREAT,且文件已存在,则出错O_TRUNC 如果文件存在,且以只读或指写方式打开,则截断文件mode: 可选参数,用于定义新建文件的访问权限,同creat函数返回值:成功文件描述符失败-1注:O_RDONL Y、O_WRONL Y、O_RDWR中只能选择一个,然后通过|运算和其它选项组合O_EXCL与O_CREAT组合实现互斥,文件已存在的情况下,调用失败。

O_WRONL Y|O_CREAT|O_TRUNC组合,则与creat函数等价对于设备文件,不能使用O_CREAT选项例:int fd=open("./test.txt",O_CREAT | O_RDWR | O_SYNC);//文件int fd=open("/dev/dsp",O_RDWR | O_SYNC); //设备4)文件读写ssize_t write(int filedes,void *buff, size_t nbytes);ssize_t read(int filedes,void *buff, size_t nbytes);filedes: 文件描述符buff:内存地址,如果用write,则先在buff内填写数据如果用read,则先准备好一个内存,等待填写nbytes:要读写的字节数返回值:成功是实际的读写长度失败-1注:read、write不仅用于读取文件,而且用于套接字、设备等。

5)文件的关闭int close(int filedes);6)文件的删除int unlink(const char * path)说明:只是将文件的引用计数减一,只有在引用计数变为0的情况下,才会删除物理文件7)移动文件指针off_t lseek(int fd,off_t offset,int whence);fd:文件描述符offset: 文件偏移量,是相对于whence的偏移whence: 文件偏移的起始位置SEEK_SET 文件头SEEK_CUR 当前位置SEEK_END 文件尾开始返回值:成功,返回新的当前文件指针位置,失败-18)设备控制(设置)#include <sys/ioctl.h>int ioctl(int d, int request, ...);d: 文件枸柄(描述符)request:用户程序对设备的控制命令,后面的省略号,是补充参数,一般最多一个返回值:成功0 失败-1例:int fd=open("/dev/dsp",O_RDWR); //打开设备int format=8; //音频采样大小int err=ioctl(fd,SNDCTL_DSP_SETFMT,&format);//SNDCTL_DSP_SETFMT // 是在soundcard.h头文件定义的宏,代表设置音频位数//&format//音频位数变量的地址int speed=44100int err=ioctl(fd,SNDCTL_DSP_SPEED,&speed);//SNDCTL_DSP_SPEED // 代表设置音频频率//&speed//频率的值ioctl是设备驱动程序中对设备的I/O通道进行管理的函数。

所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率、马达的转速等等。

Linux Kernel中提供了一些宏,这些宏标明这个命令对应的设备类型、设备序列号、数据传送方向和数据传输尺寸。

不同的设备都有一组相应宏,需要根据不同设备的说明进行使用3.函数应用文件操作的流程open -> [ioctl] -> write(read)->close其中ioctl用于设置设备,可根据情况使用1)标准输入、标准输出、标准错误输出在linux进程启动时,内核默认为每个进程打开3个文件:标准输入文件、标准输出文件、标准错误输出文件。

这三个文件也分配了文件描述符,分别为0、1、2标准输入文件被映射至键盘标准输出文件和标准错误输出文件被映射至监视器对这三个文件的描述符可以使用直接数字,也可以使用它们的宏定义:STDIN_FILENO、STDOUT_FILENO、STDDERR_FILENO例:用标准输入输出进行读写(即scanf和printf)#include <stdio.h>int main(){char buf[256];int size=read(0,buf,256); //0是标准输入描述符printf("-------------%d\n",size);write(1,buf,size); //1是标准输出描述符}2)对普通文件的操作#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <fcntl.h>//#include <unistd.h> 在C++内加入的头例1:创建文件,并写入数据int main(int argc,char **argv){int fd=open("./test.txt",O_CREAT | O_RDWR);if (fd==-1) {printf("open err\n");return 0;}char buf[256]="aaaaaaaaaaaaaaaaaaaaaa";ssize_t size=write(fd,buf,strlen(buf));printf("size=%d,len=%d\n",size,strlen(buf));close(fd);return 0;}例2:将一个文件内的数据写入到另一个文件int main(int argc,char **argv){int desfd=open("./new.txt",O_CREAT | O_WRONL Y);if (desfd==-1) {printf("open err\n");return 0;}int srcfd=open("./test.txt",O_RDONL Y);if (srcfd==-1) {printf("open err\n");return 0;}int filelen=lseek(srcfd,0,SEEK_END);lseek(srcfd,0,SEEK_SET);char buf[256];int len,size=0;while(size<filelen){len=read(srcfd,buf,1);len=write(desfd,buf,len);size+=len;}close(srcfd);close(desfd);return 0;}3).音频设备操作声卡支持的所有采样格式可以在头文件soundcard.h中找到设置采样时的声道数目SNDCTL_DSP_STEREO 0代表1声道1代表2声道设置采样时的频率SNDCTL_DSP_SPEED 8000 11025 12000 22050 37800 44100 设置采样大小SNDCTL_DSP_SETFMT 8 16#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <fcntl.h>#include <linux/soundcard.h>#include <unistd.h>static int isstop=1;static int ispause=0;void setvol(int lvol,int rvol){int fd=open("/dev/mixer",O_RDWR);short vol=(lvol<<8 | rvol); //音量,用16位整数记录左右声道音量//ioctl(fd,MIXER_READ(SOUND_MIXER_VOLUME),&vol);//读音量ioctl(fd,MIXER_WRITE(SOUND_MIXER_VOLUME),&vol);//设音量close(fd);//lvol 1 0000001// 0000000100000000//rvol 2 0000010// 0000000100000010}void getvol(int lvol,int *rvol){int fd=open("/dev/mixer",O_RDWR);short vol=(lvol<<8 | rvol); //音量,用16位整数记录左右声道音量ioctl(fd,MIXER_READ(SOUND_MIXER_VOLUME),&vol);//读音量//ioctl(fd,MIXER_WRITE(SOUND_MIXER_VOLUME),&vol);//设音量close(fd);//lvol 1 0000001// 0000000100000000//rvol 2 0000010// 0000000100000010void plays(int b,int c,int s,char *file){int i,bits=b;int channels=c;int speed=s;char filename[256];strcpy(filename,file);//////////////////////////////////////////////////////////int dsp_fd=open("/dev/dsp",O_RDWR);if (dsp_fd==-1) return ;ioctl(dsp_fd,SNDCTL_DSP_STEREO,&channels);ioctl(dsp_fd,SNDCTL_DSP_SETFMT,&bits);ioctl(dsp_fd,SNDCTL_DSP_SPEED,&speed);int fd=open(filename,O_RDONL Y);int size=lseek(fd,0,2);lseek(fd,0,0);char buf[256];for(i=0;i<size;){if(isstop) break;while (ispause) usleep(50000);printf("%d ",i);int len=read(fd,buf,256);write(dsp_fd,buf,256);i+=len;}close(fd);close(dsp_fd);}int main(int argc,char **argv){int i,bits=8; //采样大小int channels=1; //0单声道,1双声道int speed=44100; //8k 11.025k 12k 22.05k 37.8k 44.1k char filename[256];strcpy(filename,"./audio1.wav");for(i=0;i<argc;i++){ //-b -c -s -fif (strcmp(argv[i],"-b")==0)bits=atoi(argv[i+1]);else if (strcmp(argv[i],"-c")==0)channels=atoi(argv[i+1]);else if (strcmp(argv[i],"-s")==0)speed=atoi(argv[i+1]);else if (strcmp(argv[i],"-f")==0)strcpy(filename,argv[i+1]);}plays(bits,channels,speed,filename);return 0;}S=R(采样频率Hz )×D(录音时间)×r(量化位数(位)) ×声道数/8 s: 字节;R:HZ;D:录音时间S;r:量化位数bit。

相关主题