代码编织梦想

一、open函数

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
​
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
功能:
    打开文件,如果文件不存在则可以选择创建。
参数:
    pathname:文件的路径及文件名
    flags:打开文件的行为标志,必选项 O_RDONLY, O_WRONLY, O_RDWR
    mode:这个参数,只有在文件不存在时有效,指新建文件时指定文件的权限
返回值:
    成功:成功返回打开的文件描述符
    失败:-1

flags详细说明

必选项:

取值含义
O_RDONLY以只读的方式打开
O_WRONLY以只写的方式打开
O_RDWR以可读、可写的方式打开

可选项,和必选项按位或起来

取值含义
O_CREAT文件不存在则创建文件,使用此选项时需使用mode说明文件的权限
O_EXCL如果同时指定了O_CREAT,且文件已经存在,则出错
O_TRUNC如果文件存在,则清空文件内容
O_APPEND写文件时,数据添加到文件末尾
O_NONBLOCK对于设备文件, 以O_NONBLOCK方式打开可以做非阻塞I/O

mode补充说明

1) 文件最终权限:mode & ~umask

2) shell进程的umask掩码可以用umask命令查看

  • umask:查看掩码(补码)
  • umask mode:设置掩码,mode为八进制数
  • umask -S:查看各组用户的默认操作权限
取值八进制含义
S_IRWXU00700文件所有者的读、写、可执行权限
S_IRUSR00400文件所有者的读权限
S_IWUSR00200文件所有者的写权限
S_IXUSR00100文件所有者的可执行权限
S_IRWXG00070文件所有者同组用户的读、写、可执行权限
S_IRGRP00040文件所有者同组用户的读权限
S_IWGRP00020文件所有者同组用户的写权限
S_IXGRP00010文件所有者同组用户的可执行权限
S_IRWXO00007其他组用户的读、写、可执行权限
S_IROTH00004其他组用户的读权限
S_IWOTH00002其他组用户的写权限
S_IXOTH00001其他组用户的可执行权限

#include <stdio.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>



int main(void)
{
    int fd = -1;

    //1.以只读方式打开一个文件  如果文件不存在就报错
    //fd = open("txt", O_RDONLY);
    //2.以只写的方式打开一个文件 如果文件不存在就报错
    //fd = open("txt", O_WRONLY);
    //3.以只写的方式打开一个文件 如果文件不存在就创建, 如果文件存在就直接打开
    //fd = open("txt", O_WRONLY | O_CREAT, 0644);
    //4.以只读的方式打开一个文件 如果文件不存在就创建
    //fd = open("txt", O_RDONLY | O_CREAT, 0644);
    //5.以读写的方式打开文件 如果文件存在就报错, 如果文件不存在就创建
    //fd = open("txt", O_RDWR | O_CREAT | O_EXCL, 0644);
    //6.以读写的方式打开一个文件 如果文件不存在就创建 如果文件存在就清零
    fd = open("txt", O_RDWR | O_CREAT | O_TRUNC, 0644);
    if (-1 == fd)
    {
        perror("open"); 
        return 1;
    }


    printf("打开文件成功....\n");


    return 0;
}

二、close函数

#include <unistd.h>
​
int close(int fd);
功能:
    关闭已打开的文件
参数:
    fd : 文件描述符,open()的返回值
返回值:
    成功:0
    失败: -1, 并设置errno

需要说明的是,当一个进程终止时,内核对该进程所有尚未关闭的文件描述符调用close关闭,所以即使用户程序不调用close,在终止时内核也会自动关闭它打开的所有文件。

但是对于一个长年累月运行的程序(比如网络服务器),打开的文件描述符一定要记得关闭,否则随着打开的文件越来越多,会占用大量文件描述符和系统资源。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>



#if 0
/* Standard file descriptors.  */
#define	STDIN_FILENO	0	/* Standard input.  */
#define	STDOUT_FILENO	1	/* Standard output.  */
#define	STDERR_FILENO	2	/* Standard error output.  */
#endif

int main(void)
{
    int fd = -1; 

    //1. 打开文件
    fd = open("txt", O_RDWR | O_CREAT, 0644);
    if (-1 == fd)
    {
        perror("open"); 
        return 1;
    }


    printf("fd = %d\n", fd);
    printf("打开文件成功....\n");

    //2. 关闭文件 释放资源
    close(fd);

    return 0;
}

 三、read函数

#include <unistd.h>
​
ssize_t read(int fd, void *buf, size_t count);
功能:
    把指定数目的数据读到内存(缓冲区)
参数:
    fd : 文件描述符
    buf : 内存首地址
    count : 读取的字节个数
返回值:
    成功:实际读取到的字节个数
    失败: - 1
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#define SIZE 128

//从文件中读数据
int main(void)
{
    int fd = -1;
    int ret = -1;

    char buf[SIZE];

    //1. 打开文件  只读的方式
    fd = open("txt", O_RDONLY);
    if (-1 == fd)
    {
        perror("open"); 
        return 1;
    }
    printf("open successfully fd = %d\n", fd);

    //2. 读文件
    memset(buf, 0, SIZE);
    //从文件中最多读取SIZE个字节保存到buf中
    ret = read(fd, buf, SIZE);
    if (-1 == ret)
    {
        perror("read"); 
        close(fd);
        return 1;
    }

    printf("buf: %s\n", buf);

    //3. 关闭文件
    close(fd);
    return 0;
}
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#define SIZE 128

int main(void)
{
    int fd = -1;
    int ret = -1;
    char buf[SIZE];

    //1. 打开文件
    fd = open("passwd", O_RDONLY);    
    if (-1 == fd)
    {
        perror("open"); 
        goto err0;
    }

    printf("打开文件ok... fd: %d\n", fd);

    //2. 循环读取数据
    while(1)
    {
        memset(buf, 0, SIZE);
        //每一次从文件中读取最多SIZE个字节
        ret = read(fd, buf, SIZE - 1); 
        if (ret < 0)
        {
            perror("read");
            break; 
        }
    
        printf("%s", buf);
    
        //读到文件结尾
        if (ret < SIZE - 1)
        {
            break; 
        }
    }

    //3. 关闭文件
    close(fd);

    return 0;
err0:
    return 1;
}

四、write函数

#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
功能:
    把指定数目的数据写到文件(fd)
参数:
    fd :  文件描述符
    buf : 数据首地址
    count : 写入数据的长度(字节)
返回值:
    成功:实际写入数据的字节个数
    失败: - 1
#include <stdio.h>
#include <string.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>


int main(void)
{
    int fd = -1;
    int ret = -1;

    //1. 打开文件
    //fd = open("txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
    //fd = open("txt", O_WRONLY | O_CREAT , 0644);
    fd = open("txt", O_WRONLY | O_CREAT | O_APPEND, 0644);
    if (-1 == fd)
    {
        perror("open"); 
        goto err0;
    }

    printf("fd = %d\n", fd);

    //2. 写文件
    ret = write(fd, "ABCDEFG", 7); 
    if (ret < 7)
    {
        perror("write"); 
    }

    //3. 关闭文件
    close(fd);

    return 0;
err0:
    return 1;
}

五、lseek函数

#include <sys/types.h>
#include <unistd.h>
​
off_t lseek(int fd, off_t offset, int whence);
功能:
    改变文件的偏移量
参数:
    fd:文件描述符
    offset:根据whence来移动的位移数(偏移量),可以是正数,也可以负数,如果正数,则相对于whence往右移动,如果是负数,则相对于whence往左移动。如果向前移动的字节数超过了文件开头则出错返回,如果向后移动的字节数超过了文件末尾,再次写入时将增大文件尺寸。
​
    whence:其取值如下:
        SEEK_SET:从文件开头移动offset个字节
        SEEK_CUR:从当前位置移动offset个字节
        SEEK_END:从文件末尾移动offset个字节
返回值:
    若lseek成功执行, 则返回新的偏移量
    如果失败, 返回-1

所有打开的文件都有一个当前文件偏移量(current file offset),以下简称为 cfo。cfo 通常是一个非负整数,用于表明文件开始处到文件当前位置的字节数。

读写操作通常开始于 cfo,并且使 cfo 增大,增量为读写的字节数。文件被打开时,cfo 会被初始化为 0,除非使用了 O_APPEND 。

#include <stdio.h>
#include <string.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#define SIZE 128

//以十六进制的方式查看文件内容
//deng@itcast:~/share/4th$ od -x txt

int main(void)
{
    int fd = -1;
    int ret = -1;

    //1. 打开文件
    fd = open("txt", O_RDWR | O_CREAT | O_TRUNC, 0644);
    if (-1 == fd)
    {
        perror("open"); 
        goto err1;
    }

    //在文件开头写七个字符
    write(fd, "ABCDEFG",  7);

    //将文件偏移30个字节
    ret = lseek(fd, 1024 * 1024, SEEK_END);
    if (-1 == ret)
    {
        perror("lseek"); 
        goto err2;
    }

    write(fd, "123456789", 9);

    //获取文件的大小
    printf("file: %ld\n", lseek(fd, 0, SEEK_END));

    //关闭文件
    close(fd);

    return 0;
err2:
    close(fd);
err1:
    return 1;
}

六、案例

1、文件的简单拷贝(不支持二进制)

#include <stdio.h>
#include <string.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#define SIZE 128

//文件的简单拷贝 不支持二进制
int main(void)
{
    int fdr = -1;
    int fdw = -1;
    int ret = -1;

    char buf[SIZE];

    //1. 以只读的方式打开第一个文件
    fdr = open("passwd", O_RDONLY);
    if (-1 == fdr)
    {
        perror("open"); 
        goto err0;
    }

    //2. 以只写的方式打开第二个文件
    fdw = open("txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (-1 == fdw)
    {
        perror("open"); 
        goto err1;
    }

    //3. 循环拷贝数据
    while(1)
    {
        //从第一个文件中读取数据
        memset(buf, 0, SIZE);
        ret = read(fdr, buf, SIZE); 
        if (ret <= 0)
        {
            perror("read");
            break; 
        }
    
        //将读取的数据写入到第二个文件中
        ret = write(fdw, buf, ret); 
        if (ret <= 0)
        {
            break; 
        }
    }

    //4. 关闭两个文件描述符
    close(fdr);
    close(fdw);

    return 0;
err1:
    close(fdr);
err0:
    return 1;
}

2、文件的简单拷贝(支持二进制)

#include <stdio.h>
#include <string.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#define SIZE 128

//文件的简单拷贝 支持二进制
int main(int argc, char **argv)
{
    int fdr = -1;
    int fdw = -1;
    int ret = -1;

    char buf[SIZE];

    //容错判断
    if (3 != argc)
    {
        printf("usage: ./a.out filename1 filename2\n"); 
        goto err0;
    }

    //1. 以只读的方式打开第一个文件
    fdr = open(argv[1], O_RDONLY);
    if (-1 == fdr)
    {
        perror("open"); 
        goto err0;
    }

    //2. 以只写的方式打开第二个文件
    fdw = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (-1 == fdw)
    {
        perror("open"); 
        goto err1;
    }

    //3. 循环拷贝数据
    while(1)
    {
        //从第一个文件中读取数据
        memset(buf, 0, SIZE);
        ret = read(fdr, buf, SIZE); 
        if (ret <= 0)
        {
            break; 
        }
    
        //将读取的数据写入到第二个文件中
        ret = write(fdw, buf, ret); 
        if (ret <= 0)
        {
            break; 
        }
    }

    //4. 关闭两个文件描述符
    close(fdr);
    close(fdw);

    return 0;
err1:
    close(fdr);
err0:
    return 1;
}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u013250861/article/details/127000556

c语言:lseek函数-----改变文件偏移量-爱代码爱编程

1.文件偏移 通常调用read或write每读写一个文件,就会改变文件的读写位置。在linux中同样可以使用lseek函数来修改文件偏移量,即读写位置。标准C库的fseek函数和系统函数lseek比较类似,fseek函数也

Linux 系统编程 --文件IO-write()、read()、lseek()函数-爱代码爱编程

author:zengzhi 1、write 函数 write(int fd, void *buf, size_t count ): 第一个参数:向哪一个文件中去写,用的是设备号;第二个参数:向这个文件中写什么内容,数组名就是一个首地址;第三个参数:向这个文件中写多少个。函数的返回值:是实际写的字节数。 //author:zengzhi #includ

关于文件I/O的5个操作函数:open/close、touch、read、write、lseek.-爱代码爱编程

头文件包含于fcntl.h open/close函数 int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode); open函数通过包含文件名的pathname寻找文件并打开, flags可选参数: O_APPEND

linux编程---C语言底层文件I/O常用文件操作函数-爱代码爱编程

底层文件IO 一、包含的头文件 <unistdio.h> <fcntl.h> 二、文件描述符与open函数与close函数 1.文件描述符fd(自己命名用以区分不同的文件) 2.open函数(打开或创建一个文件) 用文件描述符去接收其返回值(int) int fd = open(char *, flag, Autho

【Linux】文件管理系统解析(I/O与缓冲区,文件描述符fd,iNode)-爱代码爱编程

目录 0.前言1.文件1.1如何理解文件?1.1 文件构成1.2 文件有哪些2.文件操作2.1 C语言文件操作2.2 系统调用文件操作2.3 两种操作的关系3.文件描述符fd3.1 什么是文件描述符?3.2 为什么有文件描述符?3.3 fd使用之重定向4. I/O与缓冲区4.1 是什么?4.2 为什么?4.3 使用方法与注意事项5. 文件管理系统5

linux系统c语言重命名文件,C语言文件操作函数-爱代码爱编程

我们也可以在模式字符串中指定打开的模式,如"rb"表示以二进制模式打开只读文件,"w+t"或"wt+"表示以文本模式打开读/写文件。 此函数返回一个FILE指针,所以申明一个FILE指针后不用初始化,而是用fopen()来返回一个指针并与一个特定的文件相连,如果成败,返回NULL。 例:  FILE *fp; if(fp=fopen("123.4

c语言 文件 lseek,文件IO编程之(二):read.write.lseek-爱代码爱编程

下面认真分析write.c函数 #include//包含必要的头文件 #include#include#include#include#include#include#define MAXSIZE int main(void) { int i,fd ,size,len;//定义有关变量 char *buf ="hello ! I am wr

Linux系统编程-文件IO-爱代码爱编程

 man 共有九卷,系统编程也就是第二卷的内容,第五卷是文件格式和规范 open函数 函数原型 参数pathname文件名 参数flags为访问方式的宏:O_RDONLY(只读),O_WRONLY(只写),O_RDWR(读写)这三个是必须加的 O_APPEND(追加),O_CREAT(创建),O_EXCL(是否存在),O_TRUNC(截断

嵌入式C语言开发 文件IO编程 open/close/read/write/stat/fstat/lstat-爱代码爱编程

open/close int fd2; fd2=open(argv[1],O_RDWR | O_CREAT | O_EXCL,0655); if(fd2==-1) { perror("open file error!"); exit(1); } printf("fd2=%d\n",fd2);

1· Linux应用编程和网络编程---Linux系统中的文件IO 笔记-爱代码爱编程

ha 目录 导入: 典型的嵌入式产品就是基于Linux系统在硬件上跑起来(系统移植工作),第二步基于Linux系统来开发应用程序实现产品功能。 什么是应用编程? 基于Linux去做系统编程,其实就是通过调用Linux的系统API来实现应用需要完成的任务。 什么是文件IO ? 文件IO就是文件的读写。 1· 文件操作的主要接口API 1·1 什么

71-文件IO:read、write函数和lseek函数-爱代码爱编程

1、read、write函数 /* #include <unistd.h> ssize_t read(int fd, void *buf, size_t count); 参数: - fd:文件描述符,open得到的,通过这个文件描述符操作某个文件 - buf:

tcp/ip网络编程:实现客户-服务器之间的通信、文件上传与下载_小明至极的博客-爱代码爱编程

TCP/IP网络编程:实现客户-服务器之间的通信、文件上传与下载 通信流程: (一)搭建服务器(server) 1. socket 创建套接字 头文件:#include<sys/types.h>

linux操作系统——文件i/o相关函数_conspicuous.的博客-爱代码爱编程

文章目录 前言一、文件I/O的相关函数1、open函数:创建或打开文件2、close函数:关闭被打开的文件3、read函数:从文件中读取数据存放到缓存区中4、write函数:将数据写入文件中5、lseek函数:更改文

linux文件io-系统io和标准io的接口函数_champlixxx的博客-爱代码爱编程

系统IO linux设计哲学 everything is a file in linux 也就是说在linux下面,操作任何东西都是在操作文件。或者说在Linux下面操作任何东西就是通过文件 的接口去实现的。 linux

5、标准c库io和linux系统io函数、虚拟地址空间、系统io文件/目录操作_linux io和c的io的关系-爱代码爱编程

1. 标准C库IO函数 对进行磁盘读写时,标准C库IO函数得到的缓冲区可以提高效率,降低写磁盘的次数;当使用网络通信时,直接调用Linux系统的IO函数,提高响应速度,及时性。 2. 标准C库IO和Linux系统IO

【linux】应用编程之c语言文件操作_linux c语言文件操作-爱代码爱编程

Linux进阶编程之文件操作 前言一、工程的创建1、目录结构2、Makefile 二、文件的操作1.创建、打开、关闭文件:open、close、creat2.读取、写入文件:re