ZetCode

C tmpfile 函数

最后修改日期:2025 年 4 月 6 日

临时文件处理对于 C 语言中安全高效的数据处理至关重要。tmpfile 函数会创建临时文件,这些文件在关闭时会自动删除。本教程将深入探讨 tmpfile,涵盖其行为、优点和实际应用。您将学习如何在不同场景下安全地创建、使用和管理临时文件。掌握 tmpfile 有助于防止文件泄露,并确保临时数据的干净处理。

什么是 tmpfile?

tmpfile 函数会创建一个以更新模式(wb+)打开的临时二进制文件。它返回一个用于文件操作的 FILE 指针。该文件会在使用 fclose 关闭时或程序终止时自动删除。tmpfile 是安全的,因为它会在系统的临时目录中创建具有唯一名称的文件。始终检查 NULL 返回值以处理潜在的创建失败。

tmpfile 基本用法

此示例演示了创建和使用临时文件的最简单方法。

basic_tmpfile.c
#include <stdio.h>

int main() {
    FILE *tmp = tmpfile();  // Create temporary file
    
    if (tmp == NULL) {
        perror("Failed to create temporary file");
        return 1;
    }

    fprintf(tmp, "This is temporary data\n");  // Write to temp file
    rewind(tmp);  // Reset file pointer
    
    char buffer[256];
    fgets(buffer, sizeof(buffer), tmp);  // Read back data
    printf("Read from temp file: %s", buffer);
    
    fclose(tmp);  // File automatically deleted
    return 0;
}

此代码使用 tmpfile 创建一个临时文件,并验证指针是否为 NULL。它写入数据,然后倒回到开头,再将数据读回。文件会在调用 fclose 时自动删除。这种模式对于不留下文件残留的短期数据处理非常有用。

将二进制数据写入临时文件

临时文件可以高效地存储二进制数据,如本示例所示。

binary_tmpfile.c
#include <stdio.h>

int main() {
    FILE *tmp = tmpfile();
    if (tmp == NULL) {
        perror("Failed to create temporary file");
        return 1;
    }

    int numbers[] = {10, 20, 30, 40, 50};
    fwrite(numbers, sizeof(int), 5, tmp);  // Write binary data
    
    rewind(tmp);
    
    int read_numbers[5];
    fread(read_numbers, sizeof(int), 5, tmp);  // Read binary data
    
    printf("Read values: ");
    for (int i = 0; i < 5; i++) {
        printf("%d ", read_numbers[i]);
    }
    printf("\n");
    
    fclose(tmp);
    return 0;
}

此示例将一个整数数组以二进制格式写入临时文件,然后将其读回。tmpfile 默认创建二进制文件(wb+ 模式),使其成为二进制操作的理想选择。数据仅在程序执行期间保留,防止敏感数据留在磁盘上。

使用 tmpfile 处理大数据

临时文件非常适合处理内存不足的大型数据。

large_data.c
#include <stdio.h>
#include <stdlib.h>

#define DATA_SIZE 1000000

int main() {
    FILE *tmp = tmpfile();
    if (tmp == NULL) {
        perror("Failed to create temporary file");
        return 1;
    }

    // Generate and write large dataset
    for (int i = 0; i < DATA_SIZE; i++) {
        double value = (double)rand() / RAND_MAX;
        fwrite(&value, sizeof(double), 1, tmp);
    }

    // Process data
    rewind(tmp);
    double sum = 0;
    double value;
    
    while (fread(&value, sizeof(double), 1, tmp) {
        sum += value;
    }

    printf("Average: %f\n", sum / DATA_SIZE);
    fclose(tmp);
    return 0;
}

此程序生成一百万个随机双精度浮点数,并将它们存储在临时文件中。然后,它将它们读回以计算平均值。使用 tmpfile 可以避免在处理大型数据集时出现内存不足的情况,同时确保自动清理。该文件充当内存的扩展,用于数据处理任务。

多个临时文件

同时管理多个临时文件以进行复杂操作。

multi_tmpfile.c
#include <stdio.h>

int main() {
    FILE *tmp1 = tmpfile();
    FILE *tmp2 = tmpfile();
    
    if (tmp1 == NULL || tmp2 == NULL) {
        perror("Failed to create temporary files");
        return 1;
    }

    fprintf(tmp1, "Data for first temporary file\n");
    fprintf(tmp2, "Data for second temporary file\n");
    
    // Process files independently
    rewind(tmp1);
    char line[256];
    fgets(line, sizeof(line), tmp1);
    printf("From tmp1: %s", line);
    
    rewind(tmp2);
    fgets(line, sizeof(line), tmp2);
    printf("From tmp2: %s", line);
    
    fclose(tmp1);
    fclose(tmp2);
    return 0;
}

此示例创建了两个临时文件并独立处理它们。每次调用 tmpfile 都会生成一个唯一的、未命名临时文件。该程序演示了如何安全地管理多个临时资源。所有文件在关闭时或程序退出时都会被自动清理。

tmpfile 的错误处理

正确处理错误可确保在使用临时文件时的健壮性。

error_handling.c
#include <stdio.h>
#include <errno.h>

int main() {
    FILE *tmp = tmpfile();
    
    if (tmp == NULL) {
        if (errno == EMFILE) {
            fprintf(stderr, "Too many open files\n");
        } else if (errno == EACCES) {
            fprintf(stderr, "Permission denied for temp directory\n");
        } else {
            perror("Unknown error creating temporary file");
        }
        return 1;
    }

    // Use the temporary file
    fprintf(tmp, "Error handling example\n");
    
    if (fflush(tmp) != 0) {
        perror("Failed to flush data");
        fclose(tmp);
        return 1;
    }
    
    fclose(tmp);
    return 0;
}

此代码演示了 tmpfile 的全面错误处理。它检查了特定的错误条件,例如打开文件过多(EMFILE)或权限问题(EACCES)。该示例还展示了如何处理写入操作错误。正确的错误管理可以防止文件操作中出现静默失败。

安全临时数据处理

tmpfile 为敏感数据提供安全的临时存储。

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

void process_sensitive_data(const char *data) {
    FILE *tmp = tmpfile();
    if (tmp == NULL) {
        perror("Failed to create secure temporary file");
        return;
    }

    // Store sensitive data temporarily
    fprintf(tmp, "%s", data);
    
    // Process data
    rewind(tmp);
    char buffer[256];
    fgets(buffer, sizeof(buffer), tmp);
    
    // Securely process data here
    printf("Processing: %s", buffer);
    
    // Data automatically wiped when closed
    fclose(tmp);
}

int main() {
    const char *secret = "Confidential information\n";
    process_sensitive_data(secret);
    return 0;
}

此示例展示了 tmpfile 如何安全地处理敏感信息。数据仅存在于内存或自动删除的临时文件中。此方法可防止敏感数据永久保留在磁盘上。文件的自动删除即使程序崩溃也能保证清理。

将 tmpfile 与其他文件操作相结合

将临时文件与标准文件操作集成以实现复杂的工作流程。

file_operations.c
#include <stdio.h>

void filter_data(FILE *input, FILE *output) {
    char line[256];
    while (fgets(line, sizeof(line), input) {
        if (line[0] != '#') {  // Filter out comment lines
            fputs(line, output);
        }
    }
}

int main() {
    FILE *input = fopen("data.txt", "r");
    if (input == NULL) {
        perror("Failed to open input file");
        return 1;
    }

    FILE *tmp = tmpfile();
    if (tmp == NULL) {
        perror("Failed to create temporary file");
        fclose(input);
        return 1;
    }

    filter_data(input, tmp);  // Process data into temp file
    fclose(input);
    
    // Use filtered data
    rewind(tmp);
    char line[256];
    printf("Filtered data:\n");
    while (fgets(line, sizeof(line), tmp)) {
        printf("%s", line);
    }
    
    fclose(tmp);
    return 0;
}

此程序从普通文件中读取数据,通过临时文件处理数据,然后输出结果。临时文件在处理过程中充当中间存储。这种模式在数据转换管道中很常见。临时文件在处理完成后会自动清理。

使用 tmpfile 的最佳实践

来源

C tmpfile 文档

本教程探讨了 C 语言中的 tmpfile 函数,并演示了其在安全、自动临时文件处理方面的用法。从基本用法到复杂的数据处理,tmpfile 为临时存储需求提供了可靠的解决方案。其自动清理可确保不留下残留文件,使其成为许多编程场景的理想选择。

作者

我叫 Jan Bodnar,是一名敬业的程序员,对编码充满热情。自 2007 年以来,我通过 1,400 多篇文章和 8 本电子书分享我的专业知识。凭借十多年的教学经验,我努力使编程变得平易近人且引人入胜。

列表 C 标准库