首页 > 系统相关 >day02(IO进程)文件IO

day02(IO进程)文件IO

时间:2024-08-26 22:50:53浏览次数:15  
标签:文件 int day02 fd IO 进程 include open

 目录

一.什么是文件IO

1.1 概念

1.2 特点

1.3 操作

二.函数接口

2.1 打开文件open()

2.2 关闭文件 close()

2.3 读写文件

2.3.1 读文件 read()

2.3.2 写文件 write()

练习:cp功能

2.4 文件定位操作

标准IO和文件IO总结

练习: 实现“head -n 文件名”命令的功能


一.什么是文件IO

1.1 概念

在posix(可移植操作系统接口)中定义的一组输入输出的函数

文件IO又称系统IO,是系统调用,是操作系统提供的接口函数。

POSIX接口 (英语:Portable Operating System Interface)可移植操作系统接口

1.2 特点

  1. 没有缓冲机制,每次都会引起系统调用。
  2. 围绕文件描述符进行操作,非负整数(>=0),依次分配。
  3. 文件IO默认打开三个文件描述符,分别是0(标准输入)、1(标准输出)和2(标准错误)。
  4. 操作除了目录d以外任意类型的文件b c - l s p
  5. 可移植性相对较差

问题:打开三个文件, 描述符分别是:3 4 5

关闭4以后,重新打开这个文件,描述符是几?

答: 还是4

问题:一个进程的文件描述符最大到几?最多能打开多少个文件描述符?最多能打开多少个文件?

答: 一个进程的文件描述符最大到1023 (0-1023), 最多能打开1024个文件描述符, 最多能打开1021(1024-3)个文件。

1.3 操作

文件文件:open

关闭文件: close

读写操作: read和write

定位操作:lseek

二.函数接口

2.1 打开文件open()

man 2 open

O_RDONLY、O_WRONLY、O_RDWR、O_CREAT、O_TRUNC、O_APPEND

w: O_WRONLY | O_CREAT | O_TRUNC

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

int open(const char *pathname, int flags);
功能:打开文件
参数:pathname:文件路径名
     flags:打开文件的方式
            O_RDONLY:只读
            O_WRONLY:只写
            O_RDWR:可读可写
            O_CREAT:不存在创建
            O_TRUNC:存在清空
            O_APPEND:追加   
返回值:成功:文件描述符
       失败:-1

当第二个参数中有O_CREAT选项时,需要给open函数传递第三个参数,指定创建文件的权限 
int open(const char *pathname, int flags, mode_t mode);
最后权限 = mode &(~umask)  
例如:指定权限为0666(8进制)
最终权限= 0666 & (~umask) = 0666 &(~0002) = 664

 666  => 110 110 110
&775     111 111 101
 664 	  110 110 100

思考:文件IO和标准IO的打开方式的对应关系

标准IO

文件IO

r

O_RDONLY

只读

r+

O_RDWR

可读可写

w

O_WRONLY | O_CREAT | O_TRUNC, 0777

只写,不存在创建,存在清空

w+

O_RDWR | O_CREAT | O_TRUNC, 0777

可读可写,不存在创建,存在清空

a

O_WRONLY | O_CREAT | O_APPEND, 0777

只写,不存在创建,存在追加

a+

O_RDWR | O_CREAT | O_APPEND, 0777

可读可写,不存在创建,存在追加

注意:O_CREAT需要指定第三个参数表示权限

2.2 关闭文件 close()

#include <unistd.h>
int close(int fd);
功能:关闭文件
参数:fd:文件描述符
#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;
    //1.打开文件
    //fd = open("a.c", O_RDONLY); //r
    fd = open("a.c", O_WRONLY | O_CREAT | O_TRUNC, 0666); //w
    if (fd < 0)
    {
        perror("open err ");
        return -1;
    }
    printf("fd: %d\n", fd);

    //2.关闭文件
    close(fd);
    return 0;
}

2.3 读写文件

2.3.1 读文件 read()

ssize_t read(int fd, void *buf, size_t count);
功能:从一个已打开的可读文件中读取数据
参数: fd  文件描述符
      buf  存放位置
      count  期望的个数
返回值:成功:实际读到的个数(小于期望值说明实际没这么多)
       返回0:表示读到文件结尾
       返回-1:表示出错,并设置errno号

2.3.2 写文件 write()

#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
功能:向指定文件描述符中,写入 count个字节的数据。
参数:fd   文件描述符
      buf   要写的内容
      count  期望写入字节数
返回值:成功:实际写入数据的个数
              失败  : -1

#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;
    char buf[32] = "";
    //1.打开文件
    fd = open("a.c", O_RDWR); //r+
    if (fd < 0)
    {
        perror("open err ");
        return -1;
    }
    printf("fd: %d\n", fd);

    //2. 读写文件
    read(fd, buf, 10);  //文件中内容为:hello
    printf("%s\n", buf); //hello

    write(fd, "world", 5);

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

练习:cp功能

文件IO实现cp功能。cp 源文件 新文件名

./a.out src dest

#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 fd1, fd2;
    if (argc != 3)
    {
        printf("err: %s <srcfile> <destfile>\n", argv[0]);
        return -1;
    }

    //1.打开两个文件
    fd1 = open(argv[1], O_RDONLY);
    if (fd1 < 0)
    {
        perror("fd1 open err");
        return -1;
    }
    fd2 = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0777);
    if (fd2 < 0)
    {
        perror("fd2 open err");
        return -1;
    }

    //2.循环读源文件,只要读到就写入目标
    char buf[32] = "";
    ssize_t n;
    while ((n = read(fd1, buf, 32)) > 0)
        write(fd2, buf, n);
    
    //while (read(fd1, buf, 1) > 0)  //或者
    //    write(fd2, buf, 1);

    //3. 关闭两个文件
    close(fd1);
    close(fd2);

    return 0;
}

2.4 文件定位操作

off_t lseek(int fd, off_t offset, int whence);
功能:设定文件的偏移位置
参数:fd:文件描述符
    offset: 偏移量  
        正数:向文件结尾位置移动
        负数:向文件开始位置
    whence: 相对位置
        SEEK_SET   开始位置
        SEEK_CUR   当前位置
        SEEK_END   结尾位置
补充:和fseek一样其中SEEK_SET,SEEK_CUR和SEEK_END和依次为0,1和2.

返回值:成功:文件的当前位置
        失败:-1
#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;

    fd = open("a.c", O_RDWR);
    if (fd < 0)
    {
        perror("open err");
        return -1;
    }

    //离开头后10个
    lseek(fd, 10, SEEK_SET);
    write(fd, "k", 1);

    off_t off = lseek(fd, 0, SEEK_END);
    printf("%ld\n", off);

    return 0;
}


标准IO和文件IO总结

标准IO

文件IO

概念

在C库中定义的一组用于输入输出的函数

在posix中定义的一组用于输入输出的函数

特点

  1. 有缓冲机制
  2. 围绕流进行操作,FILE*
  3. 默认打开三个流:stdin/stdout/stderr
  4. 只能操作普通文件
  5. 可移植性较强
  1. 没有缓冲机制
  2. 围绕文件描述符进行操作,非负整数
  3. 默认打开三个文件描述符:0 1 2
  4. 可以操作除了目录以外任何类型文件
  5. 可移植性相对较弱

函数

打开文件:fopen/freopen

关闭文件: flose

读文件:fgetc/fgets/fread

写文件:fputc/fputs/fwrite

定位操作: rewind/fseek/ftell

打开文件: open

关闭文件: close

读文件: read

写文件: write

定位操作: lseek

练习: 实现“head -n 文件名”命令的功能

思路:循环读,读到就累加行数,并且打印到终端,判断是否达到最后一行,达到就退出。

实现“head -n 文件名”命令的功能

例:head -3 test.c -> ./a.out -3 test.c

atoi: "123" -> 123(整型)

argv[1]: "-3" 的首地址

argv[1]+1: "3" 的首地址

atoi(argv[1]+1) ==> 3

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

int main(int argc, char const *argv[])
{
    if (argc != 3)
    {
        printf("err: %s -n <filename>\n", argv[0]); //./a.out -n <filename>
        return -1;
    }

    FILE *fp = fopen(argv[2], "r");
    if (fp == NULL)
    {
        perror("fopen err");
        return -1;
    }

    //获取行数
    int num = atoi(argv[1] + 1); // +1是为了向后偏移一个地址单位把-去掉获取到要打印的行数

    char buf[32] = "";
    int len = 0;

    //循环读,然后数换行,打印到终端,如果是最后一行就退出
    while (fgets(buf, 32, fp) != NULL)
    {
        if (buf[strlen(buf) - 1] == '\n')     //数换行
            len++;

        if (len > num)    //达到行数就退出
            break;

        fputs(buf, stdout); //打印内容到终端
    }
    fclose(fp);
    return 0;
}

标签:文件,int,day02,fd,IO,进程,include,open
From: https://blog.csdn.net/QR70892/article/details/141575554

相关文章

  • 语言图像模型大一统!Meta将Transformer和Diffusion融合,多模态AI王者登场
    前言 就在刚刚,Meta最新发布的Transfusion,能够训练生成文本和图像的统一模型了!完美融合Transformer和扩散领域之后,语言模型和图像大一统,又近了一步。也就是说,真正的多模态AI模型,可能很快就要来了!欢迎关注公众号CV技术指南,专注于计算机视觉的技术总结、最新技术跟踪、经典论文解读......
  • 内存管理-31-进程内存占用-2-/proc/pid/statm
    基于msm-5.4一、初探1.打印格式#cat/proc/593/statm//非内核线程2826695224031784814200127170//以PAGE_SIZE为单位#cat/proc/187/statm//内核线程0000000打印成员介绍:1:size:打印的是mm->total_vm的值,表示任务占用虚拟地址空间大小,单位PAGE......
  • 内存管理-31-进程内存占用-3-/proc/pid/maps‌
    基于msm-5.4一、初探此文件描述了进程使用的每个内存段的信息,但是并不是所有的段,也不是一个段的所有部分都加载到内存中了,除非使用了对应的页面。1.打印格式#cat/proc/593/maps5e0cb16000-5e0cc1a000r--p00000000fc:03100868352/system/bin/su......
  • 内存管理-31-进程内存占用-4-/proc/pid/smaps
    基于msm-5.4一、初探1.打印格式#cat/proc/593/smaps...7e5a528000-7e5a626000r--p0000000000:1f5/dev/binderfs/hwbinderSize:1016kBKernelPageSize:4kBMMUPageSize:4kBRss:......
  • 内存管理-31-进程内存占用-1-/proc/pid/status
    基于msm-5.4一、初探1.打印格式#cat/proc/593/statusName:surfaceflinger...VmPeak:11322904kBVmSize:11306812kBVmLck:0kBVmPin:0kBVmHWM:92828kBVmRSS:91100kBRssAnon:19708kBRssFile:70884kB......
  • LaViT:Less-Attention Vision Transformer的特性与优点
    引言https://arxiv.org/pdf/2406.00427随着计算机视觉领域的发展,视觉Transformer(ViTs)逐渐成为一项重要技术。尽管ViTs在捕捉图像中的长距离依赖关系方面表现出色,但其沉重的计算负担和潜在的注意力饱和问题一直是实际应用的障碍。为解决这些问题,微软提出了Less-AttentionV......
  • 062 Finishing the Core Functionality
    示例index.html<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"/><metaname="viewport"content="width=device-width,initial-scale=1.0"/><title>VueBa......
  • 正则表达式(Regular Expression)
    正则表达式(RegularExpression)是一种文本模式,包括普通字符(例如,a到z之间的字母)和特殊字符(称为"元字符"),可以用来描述和匹配字符串的特定模式,是一种用于模式匹配和搜索文本的工具,提供了一种灵活且强大的方式来查找、替换、验证和提取文本数据。概括:正则表达式是制定特定的......
  • 自动化开发流程:使用 GitHub Actions 进行 CI/CD
    在现代软件开发过程中,持续集成(ContinuousIntegration,CI)和持续部署(ContinuousDeployment,CD)是确保高质量软件交付的关键组成部分。GitHubActions提供了一种简便的方式来实现CI/CD流程的自动化。本文将介绍如何设置和使用GitHubActions来自动化你的项目部署流程。......
  • IO进程(标准IO)
    3.3.3二进制读写fread()和fwrite()size_tfread(void*ptr,size_tsize,size_tnmemb,FILE*stream);功能:从文件流读取多个元素(将二进制数据从文件读出)参数:ptr:是一个指针,是存放数据的存储空间的起始地址,用来存放读取元素size:元素大小sizeof(元素数据......