linux系统编程之文件与I/O(一):文件的打开关闭

一、文件描述符

对于Linux而言,所有对设备或文件的操作都是通过文件描述符进行的。当打开或者创建一个文件的时候,内核向进程返回一个文件描述符(非负整数)。后续对文件的操作只需通过该文件描述符,内核记录有关这个打开文件的信息(file结构体)。 一个进程启动时,默认打开了3个文件,标准输入、标准输出、标准错误,对应文件描述符是0(STDIN_FILENO)、1(STDOUT_FILENO)、2(STDERR_FILENO),这些常量定义在unistd.h头文件中。

fileno:将文件指针转换为文件描述符 fdopen:将文件描述符转换为文件指针

二、什么是I/O

输入/输出是主存和外部设备之间拷贝数据的过程 设备->内存 (输入操作) 内存->设备 (输出操作) 高级I/O ANSI C提供的标准I/O库称为高级I/O,通常也称为带缓冲的I/O 低级I/O 通常也称为不带缓冲的I/O

三、文件的打开关闭

open系统调用1:

函数原型 int open(const char *path, int flags); 参数 path :文件的名称,可以包含(绝对和相对)路径 flags:文件打开模式 返回值: 打开成功,返回文件描述符;打开失败,返回-1

open系统调用2:

函数原型 int open(const char *path, int flags,mode_t mode); 参数 path :文件的名称,可以包含(绝对和相对)路径 flags:文件打开模式 mode:  用来规定对该文件的所有者,文件的用户组及系 统中其他用户的访问权限 返回值: 打开成功,返回文件描述符;打开失败,返回-1

打开文件的方式:

O_RDONLY 打开一个供读取的文件 O_WRONLY 打开一个供写入的文件 O_RDWR 打开一个可供读写的文件 O_APPEND 写入的所有数据将被追加到文件的末尾 O_CREAT 打开文件,如果文件不存在则建立文件 O_EXCL 如果已经置O_CREAT且文件存在,则强制open() 失败 O_TRUNC 在open() 时,将文件的内容清空

O_CLOEXEC 在进行exec进程替换时关闭打开的文件描述符。

 Specifying this flag permits a program to avoid additional  fcntl(2) F_SETFD operations to set the FD_CLOEXEC flag. 

O_NONBLOCK 非阻塞模式

访问权限:

S_IRUSR 文件所有者的读权限位 S_IWUSR 文件所有者的写权限位 S_IXUSR 文件所有者的执行权限位 S_IRWXU S_IRUSR | S_IWUSR | S_IXUSR S_IRGRP 文件用户组的读权限位 S_IWGRP 文件用户组的写权限位 S_IXGRP 文件用户组的执行权限位 S_IRWXG S_IRGRP | S_IWGRP | S_IXGRP S_IROTH 文件其他用户的读权限位 S_IWOTH 文件其他用户的写权限位 S_IXOTH 文件其他用户的执行权限位 S_IRWXO S_IROTH | S_IWOTH | S_IXOTH

为了重新利用文件描述符,用close()系统调用释放打开的文件描述符  函数原型:int close(int fd); 函数参数: fd :要关闭的文件的文件描述符 返回值: 如果出现错误,返回-1;调用成功返回0

示例程序如下:

/*************************************************************************
    > File Name: file_oper.c
    > Author: Simba
    > Mail: dameng34@163.com
    > Created Time: Sat 23 Feb 2013 02:34:02 PM CST
 ************************************************************************/
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>

// #define ERR_EXIT(m) (perror(m), exit(EXIT_FAILURE))
#define ERR_EXIT(m) \
    do { \
        perror(m); \
        exit(EXIT_FAILURE); \
    } while(0)

/* fileno:将文件指针转换为文件描述符
 * fdopen:将文件描述符转换为文件指针
 */
int main(void)
{
    printf("fileno(stdin) = %d\n", fileno(stdin));

    int fd;
    /*  fd = open("test.txt", O_RDONLY);

        if (fd == -1) {
            // perror("open error");
            fprintf(stderr, "open error with errno=%d:%s\n", errno, strerror(errno));
            exit(EXIT_FAILURE);
        }
    */
    /*
        if (fd == -1)
            ERR_EXIT("open error");
        printf("open success.\n");
    */
    umask(0); //不继承shell的umask值,重新设置为0; newmode = mode & ~umask
    fd = open("test.txt", O_WRONLY | O_CREAT, 0666);
    if (fd == -1)
        ERR_EXIT("open error");
    printf("open success.\n");
    close(fd);

    return 0;
}

输出为:

fileno(stdin) = 0 open success.

需要说明的是,在linux系统编程中使用的一些系统调用函数一般如果失败返回-1且会置全局变量errno为特定的错误码,可以使用perror打印,或者通过strerror(errno)打印错误提示。

参考:《APUE》

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Ryan Miao

命令行打印文件树列表: tree

Linux & Mac 1.下载tree lib //mac brew install tree //centos yum install tree //ubu...

2986
来自专栏c#开发者

如何在DataGrid里面产生滚动条而不滚动题头

我们在开发的时候一定遇到,使用DataGrid的时候由于不想分页(数据没有那么多)但是又显示不在一页里面,此时我们希望在DataGrid里面出现一个滚动条,可以...

33111
来自专栏林德熙的博客

jekyll 如何加密博客 防止抓取

经常会发现自己的博客被一些垃圾网站抓取,我就在博客进行加密,在访问的时候进行解密,于是爬虫如果不执行js就无法获得内容。 本文告诉大家如何加密博客。

571
来自专栏阿杜的世界

Spring+Velocity+Mybatis整合笔记(step by step)

开发过程中使用的操作系统是OS X,关于软件安装的问题请大家移步高效的Mac环境设置。 本文是我对自己学习过程的一个回顾,应该还有不少问题待改进,例如目录的设...

621
来自专栏冷冷

【springboot】 springboot 整合mybatis-plus

springboot整和mybatis-plus 整合步骤 1.pom.xml 添加mp依赖 <!-- mybatis-plus begin --> <depe...

3339
来自专栏软件开发

前端MVC Vue2学习总结(七)——ES6与Module模块化、Vue-cli脚手架搭建、开发、发布项目与综合示例

使用vue-cli可以规范项目,提高开发效率,但是使用vue-cli时需要一些ECMAScript6的知识,特别是ES6中的模块管理内容,本章先介绍ES6中的基...

926
来自专栏智能大石头

5,ORM组件XCode(动手)

本篇才真正是XCode教程第一篇。《速览》是为了以最简洁的语言最短小的篇幅去吸引开发者;《简介》则是对XCode组件和XCode开发模式的一个整体介绍,让开发者...

1889
来自专栏李蔚蓬的专栏

实战LitePal(Android_Persistent Technology)

1.Debugexperience about SQLite & LitePal:创建数据库闪退?注意小括号

993
来自专栏我的技术专栏

Linux系统编程:基本I/O系统调用

833
来自专栏salesforce零基础学习

salesforce 零基础学习(五十三)多个文件生成一个zip文件(使用git上封装的代码)

此篇参考git代码:https://github.com/pdalcol/Zippex 学习salesforce可以访问一个朋友的网站:https://www....

1787

扫码关注云+社区