zoukankan      html  css  js  c++  java
  • Linux文件I/O(一)

    概述

    文件操作符

    文件是操作系统的一个重要概念。所有执行I/O操作的系统调用都以文件描述符,一个非负整数,来指代打开的文件。可以用来表示所有类型的已打开文件(pipe,FIFO,socket,终端,设备,普通文件),针对每个进程,文件描述符自成一套。

    一般大多数程序都使用三种标准的文件描述符。包括shell。

    标准文件描述符

    文件描述符 用途 POSIX名称 stdio流
    0 标准输入 STDIN_FILENO stdin 
    1 标准输出 STDOUT_FILENO stdout
    2 标准错误 STDERR_FILENO stderr

     

    执行文件I/O操作的4个主要系统调用:

    • fd = open(pathname,flags,mode) 打开pathname所标识的文件,并返回文件描述符,用以在后面的程序中表示打开的文件。如果文件不存在,则可以设置flags位来决定是否创建新文件,flags还可以确定以什么模式打开文件(只读,只写,读写)。如果文件是新创建的,则可以设置mode参数决定文件的访问模式。如果没有创建新文件,可以忽略mode 参数。
    • numread = read(fd,buffer,count) 调用从fd所指代的打开文件,从中读取最多count字节的数据,存至buffer中。read返回实际读取的字节数给numread。实际上,若在一次读取中遇到文件结束符EOF,返回值不等于count。
    • numwritten = write(fd,buffer,count) 向fd所指代的文件中写入至多count字节,这些字节来自于buffer中。write返回实际写入的字节数。
    • status = close(fd) 在对文件的操作都结束后,调用close(),释放文件描述符以及与之相关的内核资源。与文件相关的内核资源可自行百度操作系统相关知识。

     使用以上系统调用可以简单实现一个copy程序,该程序从命令行读取两个参数(源文件path,新文件path),copy一个文件。

    程序清单如下:

     1 /* copy.c
     2 
     3    Copy the file named argv[1] to a new file named in argv[2].
     4 */
     5 #include <sys/stat.h>
     6 #include <fcntl.h>
     7 #include <stdio.h>
     8 #include <stdlib.h>
     9 
    10 #ifndef BUF_SIZE        /* Allow "cc -D" to override definition */
    11 #define BUF_SIZE 1024
    12 #endif
    13 
    14 int
    15 main(int argc, char *argv[])
    16 {
    17     int inputFd, outputFd, openFlags;
    18     mode_t filePerms;
    19     ssize_t numRead;
    20     char buf[BUF_SIZE];
    21 
    22     /* Open input and output files */
    23 
    24     inputFd = open(argv[1], O_RDONLY);
    25     if (inputFd == -1) {
    26         printf("openning file %s failture",  argv[1]);
    27         exit(EXIT_FAILURE);
    28     }
    29 
    30     openFlags = O_CREAT | O_WRONLY | O_TRUNC;
    31     filePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP |
    32                 S_IROTH | S_IWOTH;      /* rw-rw-rw- */
    33     outputFd = open(argv[2], openFlags, filePerms);
    34     if (outputFd == -1) {
    35         printf("openning file %s failture",  argv[2]);
    36         exit(EXIT_FAILURE);
    37     }
    38 
    39     /* Transfer data until we encounter end of input or an error */
    40 
    41     while ((numRead = read(inputFd, buf, BUF_SIZE)) > 0)
    42         if (write(outputFd, buf, numRead) != numRead) {
    43               printf("Can not write whole file!");
    44               exit(EXIT_FAILURE);
    45         }
    46            
    47     if (numRead == -1) {
    48          printf("Read failure!");
    49          exit(EXIT_FAILURE);
    50     }
    51 
    52     if (close(inputFd) == -1) {
    53         printf("close file error!");
    54         exit(EXIT_FAILURE);
    55     }
    56     if (close(outputFd) == -1) {
    57         printf("close file error!");
    58         exit(EXIT_FAILURE);
    59     }
    60     exit(EXIT_SUCCESS);
    61 }

    通用I/O

    UNIX I/O模型的显著特点是其输入/输出的通用性概念。这意味着使用上面4个系统调用可以对所有类型的文件执行I/O操作,包括终端之类的设备,因此,仅使用这些系统调用编写的程序将对任何类型的文件有效。


    I/O调用详解

    open:打开文件

    函数原型:int open (const char *pathname, int flags, .../* mode_t mode */)

    返回值

    调用成功:返回fd文件描述符

    调用失败:返回-1 ,置errno为相应的错误标志

    pathname

    pathname标识要打开的文件, 如果pathname是符号链接,则会自动对其进行解引用。

    flags

    flags为位掩码,用于指定文件访问模式,常用的如下

    O_RDONLY   以只读方式打开

    O_WRONLY  以只写方式打开

    O_RDWR      以读写方式打开

    三种里每次只可以以一种方式打开

    其它一些重要的模式:

    O_CREATE   如果文件不存在,则创建空文件,一般这种情况下需要提供mode参数,不然新文件的权限将是栈中的随机值

  • 相关阅读:
    2011年 CIO简历该怎么写?
    OC内存管理
    【Android游戏开发十五】关于Android 游戏开发中 OnTouchEvent() 触屏事件的性能优化笔记!
    【Android游戏开发十二】(保存游戏数据 [上文])详解SharedPreference 与 FIleInputStream/FileOutputStream将数据存储到SD卡中!
    ORA16014: 日志 1 的序列号 83 未归档, 没有可用的目的
    【Android游戏开发十四】深入Animation,在SurfaceView中照样使用Android—Tween Animation!
    2011来临 IT人员应该具备哪些技能?
    垃圾控件DatePicker
    【Android游戏开发十八】解放手指,利用传感器开发游戏!(本文讲解在SurfaceView中用重力传感器控制圆球的各方向移动)
    【Android游戏开发十三】(保存游戏数据 [下文])详解SQLite存储方式,并把SQLite的数据库文件存储在SD卡中!!!
  • 原文地址:https://www.cnblogs.com/wizardwsq/p/4849679.html
Copyright © 2011-2022 走看看