标准I/O流和系统 I/O流—C语言标准IO

标准 I/O 流(Standard I/O Stream)和 系统 I/O 流(System I/O Stream)是两种文件和流操作方式,主要区别在于它们的设计层次、缓冲机制以及易用性。以下是详细的比较:


1. 层次和定位

标准 I/O 流系统 I/O 流
是 C 标准库(<stdio.h>)的一部分,提供了一组高层抽象的文件操作接口。是 POSIX 系统调用的一部分,直接与操作系统交互,用于底层文件操作。
封装了系统 I/O 流,提供了易用的、高效的接口。更接近内核,通常提供更直接的文件描述符操作。

2. 缓冲机制

标准 I/O 流系统 I/O 流
使用 缓冲机制,会在内存中维护一个缓冲区以提高性能。无缓冲机制,每次 I/O 操作都会直接触发系统调用,效率可能较低。
通过 setvbufsetbuf 设置缓冲类型和大小。不提供缓冲功能,操作结果直接反映在文件系统上。
示例:
  • 标准 I/O 流缓冲机制:
    • 数据被暂存在用户空间的缓冲区中,只有在缓冲区满或者调用 fflush 时才写入文件。
  • 系统 I/O 流无缓冲:
    • 调用 write 立即触发系统调用,将数据写入文件。

3. 文件表示方式

标准 I/O 流系统 I/O 流
使用 FILE* 类型作为文件流对象的表示。使用文件描述符(int 类型)表示打开的文件。
FILE* 是高级抽象,提供了额外的功能如格式化 I/O(printfscanf)。文件描述符是一个简单的整数,仅表示打开文件的内核索引。

示例:

// 标准 I/O 流
FILE *fp = fopen("example.txt", "r");
// 系统 I/O 流
int fd = open("example.txt", O_RDONLY);

4. 函数接口

标准 I/O 流系统 I/O 流
提供了高级接口,如 fopenfprintffgetsfread 等,适合格式化、缓冲和字符串操作。提供了底层接口,如 openwriteread 等,适合直接文件和设备操作。
标准 I/O 流:
FILE *fp = fopen("file.txt", "w");
fprintf(fp, "Hello, World!\n");
fclose(fp);
系统 I/O 流:
#include <fcntl.h>
#include <unistd.h>

int fd = open("file.txt", O_WRONLY | O_CREAT, 0644);
write(fd, "Hello, World!\n", 14);
close(fd);

5. 错误处理

标准 I/O 流系统 I/O 流
使用 errno 结合函数如 perrorferror 检查错误状态。直接通过返回值判断,-1 表示错误,同时 errno 设置为具体错误代码。
示例:

总结

对比点标准 I/O 流系统 I/O 流
表示方式FILE*文件描述符(整数)
缓冲机制有缓冲(性能较高)无缓冲(精确控制 I/O)
函数接口高级接口,如 fopenfprintf底层接口,如 openwrite
错误处理错误标志 + errno返回值 + errno
适用场景常规文件操作、文本处理设备文件操作、随机访问、大量数据传输

  • 标准 I/O 流错误处理:
    FILE *fp = fopen("nonexistent.txt", "r");
    if (fp == NULL) {
        perror("Error opening file");
    }
    

  • 系统 I/O 流错误处理:
    int fd = open("nonexistent.txt", O_RDONLY);
    if (fd == -1) {
        perror("Error opening file");
    }
    
     

1. fopenfclose

用于打开和关闭文件。

FILE *fopen(const char *filename, const char *mode);
int fclose(FILE *stream);

 示例:

#include <stdio.h>

int main() {
    FILE *file = fopen("example.txt", "w"); // 打开文件用于写入
    if (file == NULL) {
        perror("Error opening file");
        return -1;
    }
    fprintf(file, "Hello, World!\n");
    fclose(file); // 关闭文件
    return 0;
}

 2. fprintffscanf

用于格式化写入和读取文件。

int fprintf(FILE *stream, const char *format, ...);
int fscanf(FILE *stream, const char *format, ...);

示例:

#include <stdio.h>

int main() {
    FILE *file = fopen("data.txt", "w+");
    if (file == NULL) {
        perror("Error opening file");
        return -1;
    }
    // 写入数据
    fprintf(file, "Name: %s, Age: %d\n", "Alice", 25);
    rewind(file); // 回到文件开头

    // 读取数据
    char name[50];
    int age;
    fscanf(file, "Name: %[^,], Age: %d", name, &age);
    printf("Read from file: Name=%s, Age=%d\n", name, age);

    fclose(file);
    return 0;
}

3. fgetsfputs

用于读取和写入字符串。

char *fgets(char *str, int n, FILE *stream);
int fputs(const char *str, FILE *stream);

示例:

#include <stdio.h>

int main() {
    FILE *file = fopen("text.txt", "w+");
    if (file == NULL) {
        perror("Error opening file");
        return -1;
    }
    // 写入字符串
    fputs("This is a test.\n", file);
    rewind(file); // 回到文件开头

    // 读取字符串
    char buffer[100];
    if (fgets(buffer, sizeof(buffer), file)) {
        printf("Read: %s", buffer);
    }

    fclose(file);
    return 0;
}

4. fputcfgetc

用于写入和读取单个字符。

int fputc(int char, FILE *stream);
int fgetc(FILE *stream);
#include <stdio.h>

int main() {
    FILE *file = fopen("chars.txt", "w+");
    if (file == NULL) {
        perror("Error opening file");
        return -1;
    }
    // 写入字符
    fputc('A', file);
    fputc('B', file);
    rewind(file);

    // 读取字符
    char ch;
    while ((ch = fgetc(file)) != EOF) {
        putchar(ch); // 输出到屏幕
    }

    fclose(file);
    return 0;
}

5. freadfwrite

用于读写二进制数据。

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

int main() {
    FILE *file = fopen("binary.dat", "wb+");
    if (file == NULL) {
        perror("Error opening file");
        return -1;
    }

    // 写入二进制数据
    int numbers[] = {1, 2, 3, 4, 5};
    fwrite(numbers, sizeof(int), 5, file);
    rewind(file);

    // 读取二进制数据
    int buffer[5];
    fread(buffer, sizeof(int), 5, file);
    for (int i = 0; i < 5; i++) {
        printf("%d ", buffer[i]);
    }
    printf("\n");

    fclose(file);
    return 0;
}

6. fflush

刷新缓冲区,将缓冲区内容写入文件。

int fflush(FILE *stream);
#include <stdio.h>

int main() {
    FILE *file = fopen("flush_example.txt", "w");
    if (file == NULL) {
        perror("Error opening file");
        return -1;
    }

    fprintf(file, "Buffered text");
    fflush(file); // 立即写入文件

    fclose(file);
    return 0;
}

7. removerename

用于删除文件或重命名文件。

int remove(const char *filename);
int rename(const char *oldname, const char *newname);
#include <stdio.h>

int main() {
    FILE *file = fopen("temp.txt", "w");
    if (file == NULL) {
        perror("Error creating file");
        return -1;
    }
    fclose(file);

    // 重命名文件
    if (rename("temp.txt", "renamed.txt") == 0) {
        printf("File renamed successfully.\n");
    } else {
        perror("Error renaming file");
    }

    // 删除文件
    if (remove("renamed.txt") == 0) {
        printf("File deleted successfully.\n");
    } else {
        perror("Error deleting file");
    }

    return 0;
}

8. feofferror

用于检查文件流的状态。

int feof(FILE *stream);    // 检查文件结束标志
int ferror(FILE *stream);  // 检查文件错误标志
#include <stdio.h>

int main() {
    FILE *file = fopen("nonexistent.txt", "r");
    if (file == NULL) {
        perror("Error opening file");
        return -1;
    }

    char ch;
    while ((ch = fgetc(file)) != EOF) {
        putchar(ch);
    }

    if (feof(file)) {
        printf("End of file reached.\n");
    }

    if (ferror(file)) {
        perror("File error occurred");
    }

    fclose(file);
    return 0;
}

9. setbufsetvbuf

用于设置文件流的缓冲区。

void setbuf(FILE *stream, char *buffer);
int setvbuf(FILE *stream, char *buffer, int mode, size_t size);
#include <stdio.h>

int main() {
    FILE *file = fopen("buffer_example.txt", "w");
    if (file == NULL) {
        perror("Error opening file");
        return -1;
    }

    char buffer[1024];
    setbuf(file, buffer); // 设置缓冲区
    fprintf(file, "Buffered data\n");
    fflush(file); // 强制写入

    fclose(file);
    return 0;
}

#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
 
   char buff[1024];
 
   memset( buff, '\0', sizeof( buff ));
 
   fprintf(stdout, "启用全缓冲\n");
   setvbuf(stdout, buff, _IOFBF, 1024);
 
   fprintf(stdout, "这里是 runoob.com\n");
   fprintf(stdout, "该输出将保存到 buff\n");
   fflush( stdout );
 
   fprintf(stdout, "这将在编程时出现\n");
   fprintf(stdout, "最后休眠五秒钟\n");
 
   sleep(5);
 
   return(0);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值