linux高级编程之文件操作:

   

        

         1、perror(const  char* msg);  用于产生一条基于其参数字符串的错误信息,错误格式是:msg指向的字符串,冒号,错误消息,换行符;

         

          2、linux文件种类:普通文件,目录文件,链接文件,设备文件;

            

          3、一个进程启动时,会自动打开三个流:标准输入流,标准输出流,标准错误处理流;对应的文件描述符是0、1、2,分别用宏 STDIN_FILENO 、STDOUT_FILENO 、STDERR_FILENO替换;

  

          4、文件描述符的范围在0--OPEN_MAX(在linux中,最大是1048576);


          5、函数open(const char *pathname, int flags, mode_t mode)

                 参数:pathname :要打开文件的路径;

                             flag :          打开的方式:只读,只写,读写必须选择其中一个,其他可以进行或运算,如追加,不存在则创建,截断为0,非阻塞方式打开;

                             mode:        指定打开该文件时使用的权限;


          6、函数read(int filedes,void *buff,size_t nbytes);

                 从当前文件偏移量开始,读取指定大小的内容到buff中;返回实际读到的字节数,出错返回-1,读到文件末尾,返回0;

                note:注意在这里读写的时候,如果buff只是一个指针变量,则不能使用sizeof()来确定读数据的大小,因为使用一个sizeof()来测量一个指针,只能返回指针本身的大小,而不是指针指向空间的大小,如果是指向的是字符串,则应该使用strlen() ,如果是其他类型,则应该视情况而定;

           

          7、函数write(int filedes,const void *buff,size_t nbyte);

                从当前文件偏移量开始,把buff中的nbyte数据写入到打开的文件中,返回实际写入的参数,如果返回值和nbyte相同,则表示写入正确,否则写入错误;写入错误的原因之一可能是磁盘已满;

 

          8、常规文件读写不会出现阻塞现象,但是从终端读写或者从网络读写,则可能出现阻塞的现象,如果open()一个设备时指定了非阻塞(O_NONBLOCK),则read 和 write 就不会出现阻塞的现象;


          9、非阻塞工作模式:

                while(1)

                {

                          非阻塞读 read(设备1);

                           if(设备1有数据到达)

                           {

                                  处理数据;

                            }


                          非阻塞读 read(设备2);

                           if(设备2有数据到达)

                           {

                                  处理数据;

                            }

                  }


            10、函数 offset lseek(int filesdes ,off_t offset, int whence)

                     作用,指定文件操作指针的偏移量;

                      offset: 偏移量的大小;

                      whence : 偏移的起始点;

                                    SEEK_SET 表示从文件开始处偏移offset个字节,

                                    SEEK_CUR 表示从当前位置开始偏移offset个字节;

                                    SEEK_END 表示将文件的偏移量设置为文件长度加offset,offset可正可负;

                     返回值:返回文件操作指针相对于文件起始位置的偏移量的大小;

                    可以使用 x = lseek(fd,0,SEEK_CUR)确定当前文件的偏移量大小;

                     打开文件时使用了O_APPEND,则文件指针会移动到文件末尾输入;            

                          

                      如果需要创建一个大文件,可以使用lseek()将文件指针偏移很大的值,然后在最后,写入字符,表示文件结束,那么这就创建了一个占有空间很大的一个文件;


            11、fcntl作用:改变访问属性,但是不改变其本身属性;


            12、ioctl() 作用,向设备发送指令;可以读取一些数据,但这些数据不能被read 或者 write 操作,ioctl操作的是控制信息,属于带外数据(out-of-band),write 操作的是带内数据(in-band);


            13、使用mmap(void *addr,size_t len, int prot, int flag, int filedes, off_t off);

                    这个函数可以将硬盘上的一部分空间映射到内存上,对内存操作,就相当于对硬盘操作,而不用再使用write 和read 函数;直接使用指针即可对文件进行操作;

                   返回值:映射空间的起始地址,不一定是addr,但是一定在指定的addr之上;

                   addr:       用户指定的映射空间地址,但实际上,不一定从这个地址开始映射;如果参数为NULL,则表示由系统选择映射的起始地址;

                   prot::       表明映射空间对磁盘的读写以及可执行权限的使能情况,

                   flag ;       表明了共享权限;MAP_SHARED_表示各个进程共享,可以修改;

                                                                 MAP_PRIVATE 表示对各个进程表现私有,其他进程对共享空间的修改,都不会影响到磁盘文件;

                   int filedes :表明要映射到内存的磁盘文件的文件描述符;

                   off  :        表示从磁盘文件的off偏移量开始映射;


             14、可以使用munmap(void *addr,size_t len)释放映射空间;


             15、truncate(const char* path, off_t length)  和 ftruncate(int fd, off_t length) 用于截取文件的一部分,如果length大于文件长度,则会将文件扩展到length大小,多出的空间每位用0表示;

                     截断并不是将被丢弃的文件擦除,而是规定了文件的作用域小了;

             16、int fsync(int filedes) 把指定文件的数据和属性都写入磁盘;

                     int fdatasync(int filedes) 把指定文件的数据部分写到磁盘;

                    void sync(void) 把修改部分排入磁盘写队列,准备写入磁盘;