【IO操作】标准IO和文件IO

发布于:2024-05-03 ⋅ 阅读:(26) ⋅ 点赞:(0)

一.标准IO和文件IO的区别

(1)一般标准IO指的是C语言的IO操作,文件IO一般指的是Linux系统调用的IO操作。标准O因为是C语言提供的标准库,所以可以在其他操作系统平台编译后可以执行,但是文件IO只能在Linux下使用,标准IO意味着可以在多个平台移植使用。

(2)Linux的IO操作是基于文件描述符的。文件描述符是一个非负整数,用于标识打开或创建的文件。Linux提供了几个系统调用函数来进行IO操作,如open、read、write、close等。

文件的打开通过open函数完成,它返回一个文件描述符。读取文件内容使用read函数,它接受文件描述符、缓冲区地址和读取字节数作为参数,并返回实际读取的字节数。写入文件内容使用write函数,它接受文件描述符、缓冲区地址和写入字节数作为参数,并返回实际写入的字节数。关闭文件使用close函数,它接受文件描述符作为参数。

(3)C语言的IO操作是基于文件指针的。文件指针是一个指向FILE结构体的指针,该结构体描述了文件的属性和缓冲区等信息。C语言提供了一些库函数来进行IO操作,如fopen、fread、fwrite、fclose等。

文件的打开通过fopen函数完成,它返回一个文件指针。读取文件内容使用fread函数,它接受文件指针、缓冲区地址、每个元素的大小和读取元素的个数作为参数,并返回实际读取的元素个数。写入文件内容使用fwrite函数,它接受文件指针、缓冲区地址、每个元素的大小和写入元素的个数作为参数,并返回实际写入的元素个数。关闭文件使用fclose函数,它接受文件指针作为参数。

(4)标准IO和文件IO都可以用来访问文件,那么他们之间有什么区别呢?

通过文件IO读写文件时,每次操作都会执行相关系统调用。这样处理的好处是可以直接读写实际文件,坏处是频繁地系统调用会增加系统开销;而标准IO可以看做是在文件IO的基础上封装了缓冲机制,先读写缓冲区,必要时再访问实际文件,从而减少系统调用次数。

文件IO中用文件描述符表示一个打开的文件,可以访问不同类型的文件(如普通文件、设备文件和管道文件)。而标准IO中用FILE(流)表示一个打开的文件,通常只用来访问普通文件

总的来说,Linux的IO操作是底层的系统调用函数,而C语言的IO操作是基于库函数的高层封装。两者都可以用来进行文件的读写操作,但使用的方式和函数有所不同。

二.标准IO

标准IO库提供了一系列函数,用于对标准输入、输出、错误流以及文件进行操作。这些函数通常在 <stdio.h> 头文件中声明。下面是一些常用的标准IO函数以及它们的功能:

  1. fopen() 函数

    #include <stdio.h> FILE *fopen(const char *pathname, const char *mode);

    参数:
       pathname:文件路径名。
       mode:文件打开模式,可以取以下值:
          "r":只读模式打开文件。
          "w":只写模式打开文件,如果文件不存在则创建文件,如果文件已存在则清空文件。
          "a":追加模式打开文件,如果文件不存在则创建文件。
          "r+":读写模式打开文件。
          "w+":读写模式打开文件,如果文件不存在则创建文件,如果文件已存在则清空文件。
          "a+":读写模式打开文件,如果文件不存在则创建文件,并在文件末尾追加数据。
    更多模式可以查阅相关文档。
    返回值:返回一个文件指针(FILE *),用于后续的文件操作。如果打开文件失败,返回 NULL,并设置 errno 来指示错误原因。
    常见用法:用于打开文件,获取文件指针,以便后续的文件操作。

  2. fclose() 函数

    #include <stdio.h> 
    int fclose(FILE *stream);
    参数:
       stream:文件指针,需要关闭的文件。
    返回值:返回 0 表示成功关闭文件,返回 EOF 表示失败,并设置 errno 来指示错误原因。
    常见用法:用于关闭一个已经打开的文件。
    
  3. fread() 函数

    #include <stdio.h> size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

    参数:
       ptr:指向存储读取数据的缓冲区。
       size:每个数据项的大小(以字节为单位)。
       nmemb:要读取的数据项的数量。
       stream:文件指针,指向要读取数据的文件。
    返回值:返回实际读取的数据项数量,如果到达文件末尾或出错返回值小于 nmemb,同时设置 errno 来指示错误原因。
    常见用法:用于从文件中读取数据。

  4. fwrite() 函数

    #include <stdio.h> size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

    参数:
        ptr:指向要写入数据的缓冲区。
       size:每个数据项的大小(以字节为单位)。
       nmemb:要写入的数据项的数量。
       stream:文件指针,指向要写入数据的文件。
    返回值:返回实际写入的数据项数量,如果出错返回值小于 nmemb,同时设置 errno 来指示错误原因。
    常见用法:用于向文件中写入数据。

  5. fseek() 函数

    #include <stdio.h> 
    int fseek(FILE *stream, long offset, int whence);
    参数:
       stream:文件指针,指向要定位的文件。
       offset:偏移量。
          whence:偏移起始位置,可以取以下值:
          SEEK_SET:文件开头。
          SEEK_CUR:当前文件位置。
          SEEK_END:文件末尾。
    返回值:返回 0 表示成功,返回非 0 表示失败,并设置 errno 来指示错误原因。
    常见用法:用于在文件中移动文件指针。
    

 

#include <stdio.h>

int main() 
{
    FILE *fp;
    char buffer[100];

    // 打开一个文件来写入数据
    fp = fopen("example.txt", "w");
    if (fp == NULL) 
	{
        printf("无法打开文件\n");
        return 1;
    }
    fprintf(fp, "这是一个用于示例的文件\n");
    fclose(fp);

    // 打开文件来读取数据
    fp = fopen("example.txt", "r");
    if (fp == NULL) 
	{
        printf("无法打开文件\n");
        return 1;
    }
    fgets(buffer, 100, fp);
    printf("读取的内容: %s", buffer);
    fclose(fp);

    return 0;
}

 执行结果:

这是一个用于示例的文件

三.文件IO 

在Linux系统中,文件I/O操作通常使用系统调用来实现。下面是一些常见的Linux文件I/O系统调用以及它们的功能:

好的,我会重新整理一下,详细说明每个函数的参数、返回值以及常见用法:

  1. open() 函数

    #include <fcntl.h> 
    int open(const char *pathname, int flags, mode_t mode);
    参数:
       pathname:文件路径名。
       flags:文件打开标志,可以取以下值的组合:
          O_RDONLY:只读模式打开文件。
          O_WRONLY:只写模式打开文件。
          O_RDWR:读写模式打开文件。
          O_CREAT:如果文件不存在,则创建文件。
          O_TRUNC:如果文件存在且为只写或读写打开,则将文件长度截断为 0,即清空文件内      容。
          O_APPEND:在文件末尾追加数据。
          等等,还有其他的标志,可根据需要组合使用。
       mode:文件权限,仅在 O_CREAT 标志被设置时有效,通常为八进制数。
    返回值:返回一个新的文件描述符(非负整数),如果打开文件失败,返回 -1,并设置 errno 来指示错误原因。
    
    常见用法:用于打开文件,获取文件描述符,以便后续的文件操作。
  2. close() 函数

    #include <unistd.h> 
    int close(int fd);
    参数:
       fd:文件描述符,需要关闭的文件。
    返回值:返回 0 表示成功关闭文件,返回 -1 表示失败,并设置 errno 来指示错误原因。
    
    常见用法:用于关闭一个已经打开的文件。
  3. read() 函数

    #include <unistd.h> 
    ssize_t read(int fd, void *buf, size_t count);
    参数:
       fd:文件描述符。
       buf:用于存放读取数据的缓冲区。
       count:要读取的字节数。
    返回值:返回实际读取的字节数,如果到达文件末尾返回 0,出错返回 -1,并设置 errno 来指示错误原因。
    
    常见用法:用于从文件中读取数据。
  4. write() 函数

    #include <unistd.h> ssize_t write(int fd, const void *buf, size_t count);

    • 参数:

      • fd:文件描述符。
      • buf:要写入的数据。
      • count:要写入的字节数。
    • 返回值:返回实际写入的字节数,出错返回 -1,并设置 errno 来指示错误原因。

    • 常见用法:用于向文件中写入数据。

  5. lseek() 函数

    #include <unistd.h> 
    off_t lseek(int fd, off_t offset, int whence);
    参数:
       fd:文件描述符。
       offset:偏移量。
          whence:偏移起始位置,可以取以下值:
          SEEK_SET:文件开头。
          SEEK_CUR:当前文件位置。
          SEEK_END:文件末尾。
    返回值:返回新的文件偏移量(以字节为单位),出错返回 -1,并设置 errno 来指示错误原因。
    
    常见用法:用于在文件中移动文件指针。
  6. fcntl() 函数

    #include <fcntl.h>
    int fcntl(int fd, int cmd, ... /* arg */ );

    参数:
         fd:文件描述符。
         cmd:操作指令,可以取以下值:

                  F_SETFD:设置文件描述符标志。

                  F_GETFD:获取文件描述符标志。

                  F_SETFL:设置文件状态标志。

                  F_GETFL:获取文件状态标志。

                 F_DUPFD:复制文件描述符。

    返回值:根据操作指令的不同有不同的含义,出错返回 -1,并设置 errno 来指示错误原因。

    常见用法:用于对文件描述符进行各种控制操作,如设置文件状态标志、获取文件状态标志等。


    如果 cmd 参数需要额外的参数,则需要将其作为可变参数传递给 fcntl() 函数。

    等等,还有其他的操作指令,具体可以查阅相关文档

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

#define BUFFER_SIZE 1024

int main() {
    int fd;
    char buffer_write[BUFFER_SIZE];
    char buffer_read[BUFFER_SIZE];
    ssize_t bytes_read;

    // 创建一个示例文件并写入内容
    fd = open("example.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (fd == -1) 
	{
        perror("无法创建文件");
        return 1;
    }
	strcpy(buffer_write,"这是一个示例文件");
    write(fd, buffer_write, strlen(buffer_write));
    close(fd);

    // 打开文件来读取数据
    fd = open("example.txt", O_RDONLY);
    if (fd == -1) 
	{
        perror("无法打开文件");
        return 1;
    }

    // 逐步读取文件内容
    while ((bytes_read = read(fd, buffer_read, BUFFER_SIZE)) > 0) 
	{
        write(STDOUT_FILENO, buffer_read, bytes_read); // 将读取的内容直接写入标准输出
    }
    if (bytes_read == -1) 
	{
        perror("读取文件失败");
        close(fd);
        return 1;
    }
    
    // 关闭文件
    close(fd);

    return 0;
}

 执行结果:

这是一个示例文件


网站公告

今日签到

点亮在社区的每一天
去签到