嵌入式Linux学习笔记第三天(文件编程)

2019-07-12 18:15发布

                                                                                嵌入式Linux学习笔记第三天           ——文件编程                  嵌入式Linux文件编程有两种方式:系统调用和库函数。常用的文件操作函数有,open、read、write、lseek。通常来说,当一个进程运行时,都会自动打开三个文件:标准输入(键盘)、标准输出(屏幕)、标准出错处理(屏幕)。这三个文件对应的文件描述符分别为0、1、2.(对应的宏为STDIN_FILENO、STDOUT_FILENO、STDERR_FILENO)。 一:系统调用:         所谓的系统调用其实就是操作系统提供给用户程序调用的一组“特殊的接口”,用户程序可以通过这个特殊的接口获得操作系统内核提供的服务。那么,为啥操作系统不直接让用户直接访问内核,还搞出个“特殊的接口”,Linux操作在安全方面考虑的比较周到,为了更好的保护内核空间,将程序运行空间分为用户空间(0-3G)和内核空间(3G-4G),它们分别运行在不同的等级上,在逻辑上是相互分离的。通常情况系,用户进程在通常情况下不允许访问内核数据,也就不能访问内核函数,它们只能操作用户数据,调用用户函数。下面介绍几个常用的函数。Creat() , open(), close(),read(), write(), lseek().         1:创建文件:int creat(const char *filename, mode_t mode)         所需头文件:#include #include #include                    Filename为创建文件的文件名(包含路径,缺省是默认为当前路径),                  Mode为创建的文件属性,S_IRUSR 可读                                                                             S_IWUSR  可写                                                                             S_IXUSR  可执行                                                                             S_IRWXU  可读可写可执行        或者是用数字表示,0无任何权限,1可执行,2可写,4可读,6可读可写; 要创建一个用户可读、可写、可执行,但是组没有权限,其他人可以读、可以执行的文件,并设置用户ID位。那么,我们应该使用的模式是1(设置用户ID)、0(不设置组ID)、7(1+2+4,读、写、执行)、0(没有权限)、5(1+4,读、执行)即10705: 参考程序: #include                    #include #include                    #include                   #include                                        viod creat_file(char *filename) {                              /*创建的文件具有什么样的属性?*/                                   if(creat(filename,0755)<0){ printf(“creat file %sfailure! ”,filename); exit(EXIT_FAILURE); } else { printf(“creat file %ssuccess! ”,filename);                                           } }                                                                 int main(int argc,char *argv[]) { int i; if(argc<2){ perror("you haven'tinput the filename,please try again! "); exit(EXIT_FAILURE);                               }                                           for(i=1;i        2:打开文件:int open(const char*pathname, flags, mode _t mode)         所需头文件:#include #include #include   pathname:被打开文件名(可包括路径名,缺省时为当前目录)
flags:文件打开的方式,参数可以通过“|”组合构成,但前3个参数不能互相重合。
    O_REONLY:只读方式打开文件
    O_WRONLY:可写方式打开文件
   O_RDWR:读写方式打开文件
    O_CREAT:如果文件不存在时就创建一个新文件,并用第三个参数为其设置权限。
    O_EXCL:如果使用O_CREAT时文件存在,则可返回错误信息。这一参数可测试文件是否存在。
    O_NOCTTY:使用本参数时,如文件为终端,那么终端不可以作为调用open()系统调用的那个进程的控制终端。
    O_TRUNC:如文件已经存在,并且以只读或只写成功打开,那么会先全部删除文件中原因数据。
    O+APPEND:以添加方式打开文件,在打开文件的同时,文件指针指向文件末尾。
    mode _t mode:被打开文件的存取权限,为8进制表示法(调用O_CREAT才需要)。
函数返回值:成功:返回文件描述符 失败:-1           3:关闭文件:int close(int fd) 所需头文件:#include

                 fd 为文件描述符,                  函数返回值:    成功:0       出错:-1          例程:#include #include #include #include #include         int main(int argc ,char *argv[]){                                int fd;                     if(argc<2){                 puts("please inputthe open file pathname! ");                             exit(1);                                }     //如果flag参数里有O_CREAT表示,该文件如果不存在,系统则会创建该文件,该文件的权限由第三个参数决定,此处为0755 //如果flah参数里没有O_CREAT参数,则第三个参数不起作用.此时,如果要打开的文件不存在,则会报错.                  //所以fd=open(argv[1],O_RDWR),仅仅只是打开指定文件                         if((fd=open(argv[1],O_CREAT|O_RDWR,0755))<0){                              perror("open file failure! ");                              exit(1);                          }else{                            printf("open file %d  success! ",fd);                                        }                        close(fd);                      exit(0); }   4:读取文件 int read(int fd, void *buf,size_t length) 所需头文件:#include
函数传入值
fd:文件描述符
buf:指定存储器读出数据的缓冲区
size_t length:指定读出的字节数
函数返回值:成功:读出的字节数0:已到达文件尾 -1:出错
在读普通文件时,若读到要求的字节数之前已达到文件的尾部,则返回字节数会小于希望读出的字节数。   5:写入文件:int write(int fd,void*buf,size_t length)
所需头文件:#include
函数传入值:
fd:文件描述符
Buf:指定存储器写入数据的缓冲区 length:指定读出的字节数
函数返回值:成功:已写的字节数-1:出错   6:、偏移函数:int lseek(int fd,off_t offset,int whence)
所需头文件:#include
           #include
函数传入值:
fd:文件描述符
Offset:偏移量,每一读写操作所需要移动的距离,单位是字节的数量,可正可负(向前移,向后移)
Whence:当前位置的基点:
    SEEK_SET:当前位置为文件开头,新位置为偏移量的大小
   SEEK_CUR:当前位置为文件指针位置,新位置为当前位置加上偏移量
    SEEK_END:当前位置为文件的结尾,新位置为文件的大小加上偏移量大小          返回值:      成功:文件相对开头的当前位移                                           出错:-1   二:库函数编程                    C库函数的文件操作实际上是独立于具体的操作系统平台的,不管是在DOS、 Windows、Linux还是在VxWorks中都是这些函数:        1:创建和打开: FILE *fopen(const char *filename,const char *mode)              所需头文件:#include              函数传入值:              Filename:打开的文件名(包含路径,缺省时为当前路径)。              Mode:打开模式,C语言中支持的打开模式如下表              其中b用于区分二进制文件和文本文件,这一点在DOS、Windows系统中是有区分的,但Linux不区分二进制文件和文本文件。              返回值:        成功:指向file的指针                                       失败:NULL   2:关闭文件:int fclose(FILE *stream)                  需头文件 #include Stream:已打开的文件指针。 函数说明 fclose()用来关闭先前fopen()打开的文件。此动作会让缓冲区内的数据写入文件中,并释放系统所提供的文件资源。 返回值    成功:返回0, 错误:返回EOF并把错误代码存到errno。              例程:    #include                               int main()                               {                                       FILE *fp;                                       fp = fopen(“HELLO.c”,”a++”);                                       if(fp == NULL)  return 0;                                       fclose(fp);                               }           3:读取文件:size_t fread(void *ptr,size_t size,size_tn, FILE *stream)                  所需头文件:#include                  函数传入值:                                   Ptr:存放读入数据的缓存区                                   Size_t size :每段读取的记录大小                                   Size_t n:读取的段数,                                   Stream:要读取的文件流(对应文件指针)                          返回值:        成功:返回实际读取到的n数目                                                   失败:EOF                          例程:                                   #include #define nmemb 3 struct test { char name[20]; int size; }s[nmemb]; main() { FILE * stream; int i; stream = fopen(“/tmp/fwrite”,”r”); fread(s,sizeof(struct test),nmemb,stream); fclose(stream); for(i=0;i4:写入文件:size_t fwrite(const void *ptr,size_t size,size_t n, FILE * stream)                                 所需头文件:#include                          函数传入值:                                   Ptr:存放读入数据的缓存区                                   Size_t size :每段读取的记录大小                                   Size_t n:读取的段数,                                   Stream:要写入的文件流(对应文件指针)                          返回值:        成功:返回实际读取到的n数目                                                   失败:EOF                          例程: #include #define set_s (x,y){strcoy(s[x].name,y);s[x].size=strlen(y);} #define nmemb 3 struct test { char name[20]; int size; }s[nmemb]; main() { FILE * stream; set_s(0,”Linux!”); set_s(1,”FreeBSD!”); set_s(2,”Windows2000.”); stream=fopen(“/tmp/fwrite”,”w”); fwrite(s,sizeof(structtest),nmemb,stream); fclose(stream); }                    5:由文件中读取一个字符:int getc(FILE * stream);                          所需头文件:#include                          函数传入值:                                   Stream:要读取的文件流(对应文件指针)                      函数说明:fgetc()从参数stream所指的文件中读取一个字符。若读到文件尾而无数据时便返回EOF。                          返回值:        成功:读取到的字符                                                   失败:EOF(已到文件尾)                          例程:    #include main() { FILE *fp; int c; fp=fopen(“exist”,”r”); while((c=fgetc(fp))!=EOF) printf(“%c”,c); fclose(fp); }                  6:由文件中写入一个字符:int fputc(int c,FILE * stream)                          所需头文件:#include                          函数传入值:                                   Stream:要写入的文件流(对应文件指针)                          返回值:        成功:写入的字符                                                   失败:EOF                          例程:#include main() { FILE * fp; chara[26]=”abcdefghijklmnopqrstuvwxyz”; int i; fp= fopen(“noexist”,”w”); for(i=0;i<26;i++) fputc(a[i],fp); fclose(fp); }                    7:移动文件流的读写位置:int fseek(FILE * stream,long offset,intwhence);                          所需头文件:#include                          函数传入值:                                   Stream:要移动的文件流(对应文件指针)                                  Offset:移动的相对量                                  Whence为移动的参考量。为下列其中一种: SEEK_SET从距文件开头offset位移量为新的读写位置。SEEK_CUR 以目前的读写位置往后增加offset个位移量。 SEEK_END将读写位置指向文件尾后再增加offset个位移量。 当whence值为SEEK_CUR 或SEEK_END时,参数offset允许负值的出现。 下列是较特别的使用方式: 1) 欲将读写位置移动到文件开头时:fseek(FILE*stream,0,SEEK_SET); 2) 欲将读写位置移动到文件尾时:fseek(FILE *stream,0,0SEEK_END);                          函数说明: fseek()用来移动文件流的读写位置。参数stream为已打开的文件指针,参数offset为根据参数whence来移动读写位置的位移数。 返回值:        成功:0                                                    失败:-1 附加说明:fseek()不像lseek()会返回读写位置,因此必须使用ftell()来取得目前读写的位置。 例程: #include main() { FILE * stream; long offset; fpos_t pos; stream=fopen(“/etc/passwd”,”r”); fseek(stream,5,SEEK_SET); printf(“offset=%d ”,ftell(stream)); rewind(stream); fgetpos(stream,&pos); printf(“offset=%d ”,pos); pos=10; fsetpos(stream,&pos); printf(“offset =%d ”,ftell(stream)); fclose(stream); }   执行结果 offset = 5 offset =0 offset=10                    8:格式化输出数据至文件:int fprintf(FILE * stream, const char *format,.......);                          所需头文件:#include 函数说明 fprintf()会根据参数format字符串来转换并格式化数据,然后将结果输出到参数stream指定的文件中,直到出现字符串结束('