首页 > 其他分享 >26_文件IO

26_文件IO

时间:2024-04-08 12:11:55浏览次数:306  
标签:文件 26 ret fd IO printf include buf

文件IO

文件描述符

​ 对于文件 IO 来说, 一切都是围绕文件操作符来进行的。 在 Linux 系统中, 所有打开的文件都有一个对应的文件描述符。

​ 文件描述符的本质是一个非负整数, 当我们打开一个文件时, 系统会给我们分配一个文件描述符。

​ 当我们对一个文件做读写操作的时候, 我们使用 open 函数返回的这个文件描述符会标识该文件,并将其作为参数传递给 read 或者 write 函数。 在 posix.1 应用程序里面, 文件描述符 0,1,2 分别对应着标准输入, 标准输出, 标准错误。

open函数

image-20240402155257092

参数 flags 可选标志:

image-20240402155312905

当参数flags=O_CREAT时,可以加上第三个参数mode表面权限

文件的权限

​ 文件的访问权限我们可以使用数字来表示:
​ 可执行 x ->1
​ 可写 w ->2
​ 可读 r ->4
​ 例:
​ 如果我们要表示可读可写,就是上述值的和,可读可写->6

代码

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

int main(int argc, char const *argv[])
{

    int fd;                                   // 文件描述符
    fd = open("a.c", O_CREAT | O_RDWR, 0666); // 不存在就创建 可读可写模式 读写权限
    if (fd < 0)
    {
        printf("open is error\n");
    }
    printf("fd is %d\n", fd);

    return 0;
}

运行结果

image-20240402162341198image-20240402162424215

发现问题: a.c的文件权限不是0666

open函数创建文件时的权限是我们设置的mode&~(umask)

image-20240402162725072

即: 0666&~(0022)

​ 110 110 110 & ~(000 010 010)

​ 110 110 110 & 111 101 101

​ 110 100 100 -> 6 4 4 -> rw - r-- r--

close函数

image-20240402171454047

代码

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

int main(int argc, char const *argv[])
{

    int fd;                                   // 文件描述符
    fd = open("a.c", O_CREAT | O_RDWR, 0666); // 不存在就创建 可读可写模式 读写权限
    if (fd < 0)
    {
        printf("open is error\n");
    }
    printf("fd is %d\n", fd);
    close(fd);
    return 0;
}

read函数

image-20240402172119201

正常读

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

int main(int argc, char const *argv[])
{

    int fd;                                   // 文件描述符
    char buf[32]={0};
    ssize_t ret;
    fd = open("a.c", O_CREAT | O_RDWR, 0666); // 不存在就创建 可读可写模式 读写权限
    if (fd < 0)
    {
        printf("open is error\n");
        return -1;
    }
    printf("fd is %d\n", fd);

    ret = read(fd, buf, sizeof(buf));
    if(ret < 0)
    {
        printf("read is error\n");
        return -2;
    }
    printf("buf is %s\n", buf);
    printf("ret is %ld\n", ret);
    close(fd);
    return 0;
}

运行结果

image-20240402172924047

生成的文件中最后多一个\n,所以一个9个字符

读到结尾再读一次

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

int main(int argc, char const *argv[])
{

    int fd;                                   // 文件描述符
    char buf[32]={0};
    ssize_t ret;
    fd = open("a.c", O_CREAT | O_RDWR, 0666); // 不存在就创建 可读可写模式 读写权限
    if (fd < 0)
    {
        printf("open is error\n");
        return -1;
    }
    // printf("fd is %d\n", fd);

    ret = read(fd, buf, sizeof(buf));
    if(ret < 0)
    {
        printf("read is error\n");
        return -2;
    }
    printf("buf is %s\n", buf);
    printf("ret is %ld\n", ret);

    ret = read(fd, buf, sizeof(buf));
    printf("ret is %ld\n", ret);

    close(fd);
    return 0;
}

运行结果

image-20240402173231443

ret返回0表示已经读到文件末尾

write函数

image-20240402173518217

代码

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

int main(int argc, char const *argv[])
{

    int fd;                                   // 文件描述符
    char *buf="hello\n";
    ssize_t ret;
    
    fd = open("a.c", O_CREAT | O_RDWR, 0666); // 不存在就创建 可读可写模式 读写权限

    if (fd < 0)
    {
        printf("open is error\n");
        return -1;
    }
    // printf("fd is %d\n", fd);
    

   write(fd, buf, sizeof(buf));

    close(fd);
    return 0;
}

运行结果

image-20240403132907496

综合练习

通过命令行操作,把a.c文件里面的内容写到b.c里面。

代码

open.c

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

int main(int argc, char const *argv[])
{
    int fd_src, fd_obj;
    ssize_t ret = 0;
    char buf[32];
    if(argc != 3)
    {
        printf("Usage:%s <src file> <obj file>\n", argv[0]);
        return -1;
    }
    fd_src = open(argv[1], O_RDONLY);
    fd_obj = open(argv[2], O_CREAT|O_WRONLY, 0666);

    while((ret = read(fd_src, buf, sizeof(buf))) != 0)
    {
        write(fd_obj, buf, ret);
    }

    close(fd_src);
    close(fd_obj);

    return 0;
}

运行结果

image-20240403140145389

lseek函数

介绍

​ 所有打开的文件都有一个当前文件偏移量(current file offset) ,以下简称为 cfo。

​ cfo 通常是一个非负整数, 用于表明文件开始处到文件当前位置的字节数。 读写操作通常开始于 cfo, 并且使 cfo 增大, 增量为读写的字节数。 文件被打开时, cfo 会被初始化为0, 除非使用了 O_APPEND 。 使用 lseek 函数可以改变文件的 cfo 。

image-20240403140603056

成功返回当前指针位置

举个例子
 把文件位置指针设置为 100 lseek(fd,100,SEEK_SET);
 把文件位置设置成文件末尾 lseek(fd,0,SEEK_END);
 确定当前的文件位置 lseek(fd,0,

标签:文件,26,ret,fd,IO,printf,include,buf
From: https://www.cnblogs.com/mzx233/p/18120846

相关文章

  • 空洞卷积 Dilated Convolution
    空洞卷积DilatedConvolution通常的卷积操作,除了需要指定输入输出通道数,还需要确定卷积核大小kernei_size、步长stride、填充大小padding。Conv1d(384,48,kernel_size=3,stride=1,padding=1)空洞卷积则是在此基础上增加了dilation参数,用于控制卷积核的扩张程度。dil......
  • ubuntu2204 部署 stable-diffusion-webui
    显卡:(一个实例仅能用一张卡)顶配:rtx6000ada48g,a10040g,a100 80g,a100 96g,a80080g,h100,h200高端:rtx409024g,rtx4090D24g,rtxa600048g,rtxa500024g,rtx5000ada32g魔改:rtx2080ti22g,rtx308020g性价比:rtx4060ti16g,rtx206012g,rtx306012g,rtx309024g,rtxtitan24g其......
  • sqlalchemy relationship lazy属性
    'select' (默认):懒加载(LazyLoading):当访问与父对象关联的子对象集合或单个对象属性时,才会触发一次SQL查询,从数据库中获取相关数据。这是最常用的加载策略,因为它延迟了数据的获取,直到真正需要时才执行查询,有助于减少不必要的数据库交互。'joined':连接加载(Joi......
  • openpyxl解析xlsx文件示例
    #coding=utf-8importopenpyxldefread_sheet(book_name,sheet_name):returnopenpyxl.load_workbook(book_name)[sheet_name]defget_pai2times(sheet,pai_col,time_col):records=dict()forrowinsheet.iter_rows(min_row=2,max_row=sheet.max......
  • KALDI-IO库的生成与读取
    https://blog.csdn.net/nwnu_908/article/details/117354174?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171254323616800184167343%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=171254323616800184167343&biz_id=0&a......
  • Visual Studio 2022插件的安装及使用 - 编程手把手系列文章
          这次开始写手把手编程系列文章,刚写到C#的Dll程序集类库的博文,就发现需要先介绍VisualStudio2022的插件的安装及使用,因为在后面编码的时候会用到这些个插件,所以有必要先对这个内容进行介绍。      其实笔者使用的VisualStudio2022的插件不多,因为有些插件......
  • WebSocket manager.js:115 GET http://IP:8000/socket.io/?EIO=4&transport=polling&t
    前言全局说明WebSocket报错net::ERR_CONNECTION_TIMED_OUT一、问题:WebSocket报错net::ERR_CONNECTION_TIMED_OUT二、原因:可能和后端的服务链接不上导致的三、解决方法:重启启动后端服务免责声明:本号所涉及内容仅供安全研究与教学使用,如出现其他风险,后......
  • springboot与springcloud版本关系,BeanCreationException Error creating bean with n
    添加注解@EnableFeignClients后报错:org.springframework.beans.factory.BeanCreationException:Errorcreatingbeanwithname'configurationPropertiesBeans'definedinclasspathresource[org/springframework/cloud/autoconfigure/ConfigurationPropertiesRebi......
  • 【mac权限】解决 mac 运行报错 150: Operation not permitted
    Couldnotsetenvironment:150:OperationnotpermittedwhileSystemIntegrityProtectionisengagedMac下操作文件,遇到Operationnotpermitted原来是索引服务被关闭,导致对文件夹的操作权限失效解决步骤打开系统偏好设置,隐私与安全性,左侧选择‘文件和文件夹’,......
  • VSCode 终端显示“pnpm : 无法加载文件 C:\Program Files\nodejs\npm.ps1,因为在此
    解决方案:1.用get-ExecutionPolicy命令在vscode终端查询状态get-ExecutionPolicy返回Restricted说明状态是禁止的2.用set-ExecutionPolicyRemoteSigned命令更改状态即可set-ExecutionPolicyRemoteSigned此时再输入get-ExecutionPolicy,显示RemoteSigned即可正常执......