Chinaunix首页 | 论坛 | 博客
  • 博客访问: 294903
  • 博文数量: 3
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 50
  • 用 户 组: 普通用户
  • 注册时间: 2019-06-06 22:08
文章分类
文章存档

2020年(1)

2019年(2)

我的朋友

分类: LINUX

2020-04-19 20:49:25

一、UNIX/Linux 的一个基本哲学是“一切皆文件”。Linux 文件按其代表的具体对象,可大致分类为:

  • 普通文件,即一般意义上的文件、磁盘文件;
  • 设备文件,代表的是系统中一个具体的设备;
  • 管道文件、FIFO 文件,一种特殊文件,常用于进程间通信;
  • 套接字(socket)文件,主要用在网络通信方面。 


二、文件 I/O 的常用操作方法有“打开”、“关闭”、“读”和“写”等。只要是文件,都可以用这套方法操作。Linux 系统提供的文件 I/O 接口函数,是以最基本的系统服务形式提供的,又称它们为基本 I/O 函数。这些函数有个共同的特点:它们都通过文件描述(fd)来完成对指定文件的 I/O 操作。 

三、在 C 语言下进行文件 I/O 编程,一般要包含程序如下所列的头文件,这些头文件定义了文件 I/O 用到的数据类型、函数原型及其它要用到的符号常量。

常用文件 I/O 操作和函数

  1. #include<sys/types.h /* 定义数据类型,如 ssize_t,off_t 等 */
  2. #include <fcntl.h>     /* 定义 open,creat 等函数原型,创建文件权限的符号常量 S_IRUSR 等 */
  3. #include <unistd.h>    /* 定义 read,write,close,lseek 等函数原型 */
  4. #include <errno.h>     /* 与全局变量 errno 相关的定义 */
  5. #include <sys/ioctl.h> /* 定义 ioctl 函数原型 */


open()函数

  1. int open(const char *pathname, int flags);
  2. int open(const char *pathname, int flags, mode_t mode);

  3. int creat(const char *pathname, mode_t mode);

   操作成功,返回值为文件描述符 fd,否则返回-1,同时设置全局变量 errno 报告具体错误的原因。


参数      打开文件标识              含义

pathname      -            C 字符串形式的文件名 

           O_RDONLY      以只读方式打开文件,与 O_WRONLY 和 O_RDWR 互斥 
           O_WRONLY      以只写方式打开文件,与 O_RDONLY 和 O_RDWR 互斥 
flags      O_RDWR        以可读写方式打开文件,与 O_WRONLY 和 O_RDONLY 互斥 
           O_CREAT       如果要打开的文件不存在,则创建该文件 
           O_EXCL        该标志与 O_CREAT 共同使用时,会去检查文件是否存在,若文件不存在则创建该文件,否则将导致打开文件失败。此外,打开文件链接时,使用该标志将导致失败 
           O_NOCTTY      如果要打开的文件为终端设备,则不把该终端设备当成控制终端 
           O_TRUNC       若文件存在且以可写方式打开,此标志会清除文件内容,并将其长度置为 0 
           O_APPEND      读写文件都从文件的尾部开始,所写入的数据会以追加的方式插入到文件末尾 
           O_NONBLOCK    以不可阻塞方式打开文件,也就是不管有无数据需要读写或者等待,都会立即返回 

mode           -         创建文件的权限模式,可以使用八进制数来表示新文件的权限,也可采用中定义的符号常量。当打开已有文件时,将忽略这个参数。


                                创建文件的权限模式

    符号常量   值         含义               符号常量   值        含义 
    S_IRWXU  0x700  所属用户读、写和执行权限  S_IRWXG  0x070  组用户读、写和执行权限 
    S_IRUSR  0x400  所属用户读权限           S_IRGRP  0x040  组用户读权限 
    S_IWUSR  0x200  所属用户写权限           S_IWGRP  0x020  组用户写权限 
    S_IXUSR  0x100  所属用户执行权限         S_IXGRP  0x010  组用户执行权限 
    S_IRWXO  0x007  其他用户读、写和执行权限  S_IWOTH  0x002  其他用户写权限 
    S_IROTH  0x004  其他用户读权限           S_IXOTH  0x001  其他用户执行权限 


    
creat()创建文件时,如果文件已存在,则会把已存在的文件内容清空、长度截为 0,然后返回对应的文件描述符;如果文件不存在,则直接创建,然后返回创建文件的描述符; 

    
当 open()的参数 flags 设置了 O_CREAT 时,如果文件已存在,则直接打开并返回文件描述符;如果文件不存在,则创建新文件,然后返回对应的文件描述符。 



close()函数

  1. int close(int fd);

    如果文件顺利关闭,返回 0,否则返回-1,同时设置全局变量 errno 报告具体错误的原因



read()函数

  1. ssize_t read(int fd, void *buf, size_t count);
    
    操作成功,返回实际读取的字节数,如果已到达文件结尾,返回 0,否则返回-1 表示出错,同时设置全局变量 errno 报告具体错误的原因。

    参数 fd 是所打开文件的描述符,buf 是数据缓冲区,存放着准备读入文件的数据,count是请求写入的字节数。实际读取的字节数,可以小于请求的字节数 count,比如下面两种情况: 
  • 文件长度小于请求的长度,即还没达到请求的字节数时,就已到达文件结尾。
  • 读设备文件时,有些设备每次返回的数据长度小于请求的字节数,如终端设备一般按行返回,即每读到一行数据,就返回。 



write()函数

  1. ssize_t write(int fd, const void *buf, size_t count);

    操作成功,返回实际写入的字节数,出错则返回-1,同时设置全局变量 errno 报告具体错误的原因。
    参数 fd 是所打开文件的描述符,buf 是数据缓冲区,存放着准备写入文件的数据,count是请求写入的字节数。实际写入的字节数可以小于请求写的字节数。




fsync()函数

  1. int fsync(int fd);

    操作成功返回 0,否则返回-1,同时设置全局变量 errno 报告具体错误的原因。

    fsync()函数的功能是进行文件数据同步,强制把已修改过的文件数据存入持久存储设备中。

    write()函数一旦返回,表明所写的数据已提交到系统内部缓存了,但此时数据并不一定已经被写入磁盘等持久存储设备中。要确保已修改过的数据全部写入持久存储设备中,正确的做法是调用 fsync 函数进行文件数据同步,强制把已修改过的文件数据写入持久存储设备中。 如果不调用 fsync(),在 write()返回后马上就复位或重新上电,则所作的修改就可能没有被更新,从而造成文件数据丢失。




文件操作实例:

file_wr.cpp

  1. #include <sys/types.h>  /* 定义数据类型,如 ssize_t, off_t等 */
  2. #include <fcntl.h>      /* 定义 open,creat 等函数原型,创建文件权限的符号常量 S_IRUSR 等 */
  3. #include <unistd.h>     /* 定义 read,write,close,lseek 等函数原型 */
  4. #include <errno.h>      /* 与全局变量 errno 相关的定义 */
  5. #include <sys/ioctl.h /* 定义 ioctl 函数原型 */
  6. #include <iostream>


  1. using std::cout;
  2. using std::endl;

  3. int main(void)
  4. {
  5.     char filename[] = "sample.txt";
  6.     char str[] = "file sample, hello wolrd!\n";
  7.     int fd = -1;
  8.     int res = 0;
  9.     char buf[128] = {0};
  10.     
  11.     fd = open(filename, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IROTH | S_IRGRP | S_IWGRP);

  12.     if (fd < 0)
  13.     {
  14.         cout << "open \"" << filename << "\"" << " file failed" << std::endl;
  15.         return -1;
  16.     }
  17.     cout << "open \"" << filename << "\"" << " successful" << endl;

  18.     res = write(fd, str, sizeof(str));
  19.     cout << "write " << res << " bytes to " << "\"" << filename << "\"" << endl;
  20.     fsync(fd);
  21.     cout << "data fsysc to file" << endl;
  22.     close(fd);
  23.     cout << "close file" << endl;

  24.     fd = open(filename, O_RDONLY);
  25.     if (fd < 0)
  26.     {
  27.         cout << "open \"" << filename << "\"" << " file failed" << std::endl;
  28.         return -1;
  29.     }

  30.     res = read(fd, buf, sizeof(buf));
  31.     buf[res] = '\0';
  32.     cout << "read " << res << " bytes from file " << "\"" << filename << "\", " << buf << endl;
  33.     close(fd);

  34.     return 0;
  35. }




对应的Makefile文件

  1. #Makefile for file_wr

  2. EXE = file_wr
  3. OBJ = file_wr.o
  4. SRC = file_wr.c

  5. CXX = g++
  6. CXXFLAGS = -g
  7. LDFLAGS =

  8. EXE:$(OBJ)
  9.     $(CXX) $(LDFLAGS) -o $(EXE) $^

  10. OBJ:$(SRC)
  11.     $(CXX) $(LDFLAGS) -o $(OBJ) -c $^

  12. .PHONY:clean
  13. clean:
  14.     -$(RM) -rvf $(OBJ) $(EXE)

    在这个范例中,先以可写方式打开当前目录下的“sample.txt”文件,如果该文件不存在,则创建文件,再往文件中写入一个字符串“file sample, hello world!\n”,把操作结果输出到终端后,关闭文件。接着再次以只读模式打开该文件,读取刚才写入的数据,并把结果输出到终端,最后关闭该文件。 



阅读(6894) | 评论(0) | 转发(0) |
0

上一篇:线程介绍

下一篇:没有了

给主人留下些什么吧!~~