测试文件复制速度

183 篇文章 1 订阅

在Linux C语言中,文件操作相关的函数和系统调用非常重要,因为它们允许你读取、写入、创建、删除和管理文件。以下是一些基本的文件操作函数的简要介绍:

1. open(): 打开或创建一个文件。这个函数需要文件路径和一个标志集合,用于指定文件访问模式(例如,只读、只写、读写)。

2. close(): 关闭一个已经打开的文件描述符。

3. read(): 从文件描述符读取数据。

4. write(): 向文件描述符写入数据。

5. lseek(): 改变文件中的当前位置,通常用于移动读写位置。

6. fsync(): 强制将缓冲区的数据写入文件,确保数据的同步。

7. stat(): 获取文件的状态信息,如大小、权限等。

8. fstat(): 类似于stat,但是使用文件描述符而不是文件名。

9. chmod(): 更改文件的权限。

10. chown(): 更改文件的所有者和/或组。

11. rename(): 重命名文件。

12. unlink(): 删除文件。

13. mkdir(): 创建目录。

14. rmdir(): 删除空目录。

15. opendir(): 打开一个目录。

16. readdir(): 读取目录内容。

17. closedir(): 关闭目录。

18. statvfs(): 获取文件系统的信息。

19. umask(): 设置文件创建时的默认权限掩码。

20. link(): 创建硬链接。

21. symlink(): 创建符号链接。

22. readlink(): 读取符号链接的目标。

23. truncate(): 截断文件到指定的大小。

24. ftruncate(): 使用文件描述符来截断文件到指定的大小。

25. lockf(): 锁定文件的一部分,以实现并发控制。

26. fcntl(): 对文件描述符执行各种控制操作,包括文件锁和文件状态标志。

这些函数是POSIX标准的一部分,因此在Unix-like系统上广泛可用,包括Linux。在使用这些函数时,需要包含相应的头文件,如`<fcntl.h>`、`<unistd.h>`、`<sys/types.h>`、`<sys/stat.h>`等。

测试代码

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <sys/time.h>

#define IN_FILE "/root/file1"
#define OUT_FILE "/root/file2"
#define BUFFER_SIZE 65536

int main(void)
{
    FILE *pReadFile, *pWriteFile;
    void *pBuff;
    int i;
    size_t uiReadSize, uiWriteSize;
    struct timespec tpstart;
    struct timespec tpend;
    double timedif;
    long l_timedif;
    size_t uiFileSize;

    uiFileSize = 0;

	pReadFile = fopen(IN_FILE , "r");
	if (NULL == pReadFile)
    {
        printf("open read file fail\n");
        return -1;
    }

	pWriteFile = fopen(OUT_FILE , "w");
	if (NULL == pWriteFile)
    {
        printf("open write file fail\n");
        return -1;
    }

    pBuff = malloc(BUFFER_SIZE);
	if (NULL == pBuff)
    {
        printf("malloc fail\n");
        return -1;
    }

    clock_gettime(CLOCK_MONOTONIC, &tpstart);   //最小单位为ns,纳秒
    for(i=0 ; i<100000 ;i++)
    {
        uiReadSize = fread(pBuff, 1, BUFFER_SIZE, pReadFile);
        if(BUFFER_SIZE > uiReadSize)
        {
            uiWriteSize = fwrite(pBuff, 1, uiReadSize, pWriteFile);
            if(uiReadSize != uiWriteSize)
            {
                printf("uiReadSize(%u) != uiWriteSize(%u)\n", uiReadSize, uiWriteSize);
            }
            else
            {
                uiFileSize += uiReadSize;
            }
            break;
        }

        uiWriteSize = fwrite(pBuff, 1, BUFFER_SIZE, pWriteFile);
        if(BUFFER_SIZE > uiWriteSize)
        {
            printf("uiWriteSize(%u) < %u\n", uiWriteSize, BUFFER_SIZE);
        }
        else
        {
            uiFileSize += uiWriteSize;
        }        
    }
    fflush(pWriteFile);
    fsync(fileno(pWriteFile));
    clock_gettime(CLOCK_MONOTONIC, &tpend);
    l_timedif = 1000000*(tpend.tv_sec-tpstart.tv_sec)+(tpend.tv_nsec-tpstart.tv_nsec)/1000; //us,微秒
    timedif = (double)l_timedif/1000000.0;  //s,秒
    printf("clock_gettime duration: %fs\n", timedif);  //clock_gettime
    printf("File size:%fMB\n", uiFileSize/1024.0/1024.0);
    printf("write test speed:%fMB/s", uiFileSize/timedif/1024.0/1024.0);
	printf("\n\n");

    fclose(pReadFile);
    pReadFile = NULL;
    fclose(pWriteFile);
    pWriteFile = NULL;

    return 0;
}

ChatGPT

在Linux系统中,使用C语言编写一个程序以测试文件复制的速度需要进行如下步骤:
1. 打开源文件和目标文件。
2. 读取源文件并将内容写入目标文件,记录这个过程的开始和结束时间。
3. 计算复制持续的时间和数据量,得到复制速度。
以下是一个简单的C程序示例,用于测试复制单个文件的速度:

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

#define BUFFER_SIZE 4096

int main(int argc, char *argv[]) {
    if (argc != 3) {
        fprintf(stderr, "Usage: %s source_file destination_file\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    int source_fd = open(argv[1], O_RDONLY);
    if (source_fd == -1) {
        perror("Error opening source file");
        exit(EXIT_FAILURE);
    }

    int dest_fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (dest_fd == -1) {
        perror("Error opening destination file");
        close(source_fd);
        exit(EXIT_FAILURE);
    }

    char buf[BUFFER_SIZE];
    ssize_t bytes_read;
    ssize_t bytes_written;
    ssize_t total_bytes_copied = 0;
    struct timespec start, end;

    clock_gettime(CLOCK_MONOTONIC, &start); // 获取开始时间

    while ((bytes_read = read(source_fd, buf, BUFFER_SIZE)) > 0) {
        bytes_written = write(dest_fd, buf, bytes_read);
        if (bytes_written < bytes_read) {
            perror("Error writing to destination file");
            close(source_fd);
            close(dest_fd);
            exit(EXIT_FAILURE);
        }
        total_bytes_copied += bytes_written;
    }

    if (bytes_read == -1) {
        perror("Error reading source file");
        close(source_fd);
        close(dest_fd);
        exit(EXIT_FAILURE);
    }

    // 数据同步确保数据完全写到磁盘
    fsync(dest_fd); 

    clock_gettime(CLOCK_MONOTONIC, &end); // 获取结束时间

    close(source_fd);
    close(dest_fd);

    double time_taken = end.tv_sec - start.tv_sec +
        (end.tv_nsec - start.tv_nsec) / 1e9; // 计算总时间(单位:秒)

    printf("Copy completed.\nTotal bytes copied: %ld\n", total_bytes_copied);
    printf("Total time taken to copy: %f seconds\n", time_taken);
    printf("Copying speed: %f bytes/second\n", total_bytes_copied / time_taken);

    return 0;
}

编译和运行程序:

gcc -o filecopy filecopy.c
./filecopy sourcefile.txt destinationfile.txt

请注意,这个简单的样例没有实现错误检查,真正的工程应用中应当处理所有可能的错误情况。
复制速度会受到很多因素的影响,比如磁盘性能、系统负载、文件系统类型和文件大小等。此代码段中使用`CLOCK_MONOTONIC`来获取一个稳定的时间基准,以尽量减小环境变化对测量结果的影响。可能需要更复杂的逻辑和额外的优化,例如使用`mmap`或更大的缓冲区来减少系统调用的次数等。

讯飞星火

要在Linux C语言中测试文件复制速度,可以使用以下代码:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/time.h>

int main(int argc, char *argv[]) {
    if (argc != 3) {
        printf("Usage: %s <source_file> <destination_file>
", argv[0]);
        return 1;
    }

    int src_fd = open(argv[1], O_RDONLY);
    if (src_fd == -1) {
        perror("Error opening source file");
        return 1;
    }

    int dst_fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (dst_fd == -1) {
        perror("Error opening destination file");
        close(src_fd);
        return 1;
    }

    struct timeval start, end;
    gettimeofday(&start, NULL);

    char buffer[4096];
    ssize_t bytes_read, bytes_written;
    while ((bytes_read = read(src_fd, buffer, sizeof(buffer))) > 0) {
        bytes_written = write(dst_fd, buffer, bytes_read);
        if (bytes_written != bytes_read) {
            perror("Error writing to destination file");
            close(src_fd);
            close(dst_fd);
            return 1;
        }
    }

    gettimeofday(&end, NULL);
    close(src_fd);
    close(dst_fd);

    double elapsed_time = (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) / 1000000.0;
    double speed = (double)bytes_written / elapsed_time;
    printf("File copied successfully!
");
    printf("Speed: %.2f MB/s
", speed / (1024 * 1024));

    return 0;
}

将上述代码保存为`file_copy_speed.c`,然后使用`gcc`编译器编译:

gcc file_copy_speed.c -o file_copy_speed

运行生成的可执行文件,传入源文件和目标文件作为参数:

./file_copy_speed source.txt destination.txt

程序将输出文件复制速度,单位为MB/s。

文心一言

在Linux C语言中,要测试文件复制的速度,你可以编写一个程序,该程序从源文件读取数据并写入目标文件,同时测量所用的时间。下面是一个简单的示例,展示如何编写这样的程序:

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <time.h>  
#include <unistd.h>  
  
#define BUFFER_SIZE 4096  // 缓冲区大小  
  
int main(int argc, char *argv[]) {  
    if (argc != 3) {  
        fprintf(stderr, "Usage: %s source_file destination_file\n", argv[0]);  
        return 1;  
    }  
  
    FILE *source = fopen(argv[1], "rb");  
    if (!source) {  
        perror("Error opening source file");  
        return 1;  
    }  
  
    FILE *destination = fopen(argv[2], "wb");  
    if (!destination) {  
        perror("Error opening destination file");  
        fclose(source);  
        return 1;  
    }  
  
    char buffer[BUFFER_SIZE];  
    size_t bytesRead;  
    clock_t start = clock();  // 开始计时  
  
    while ((bytesRead = fread(buffer, 1, BUFFER_SIZE, source)) > 0) {  
        fwrite(buffer, 1, bytesRead, destination);  
    }  
  
    clock_t end = clock();  // 结束计时  
    double elapsedTime = (double)(end - start) / CLOCKS_PER_SEC;  // 计算用时  
  
    size_t totalBytes = ftell(source);  // 获取源文件大小  
    double speed = (double)totalBytes / elapsedTime / (1024 * 1024);  // 计算复制速度(MB/s)  
  
    printf("Copied %zu bytes in %.2f seconds. Speed: %.2f MB/s\n", totalBytes, elapsedTime, speed);  
  
    fclose(source);  
    fclose(destination);  
    return 0;  
}

这个程序接受两个命令行参数:源文件和目标文件的路径。它打开一个源文件以进行读取,并打开一个目标文件以进行写入。然后,它使用一个缓冲区来从源文件读取数据,并将数据写入目标文件。在复制过程中,程序使用clock()函数来测量经过的时间。复制完成后,程序计算总复制速度和用时,并将结果打印到标准输出。

要编译和运行此程序,请将其保存为file_copy_speed.c,然后在终端中执行以下命令:

gcc -o file_copy_speed file_copy_speed.c  
./file_copy_speed source_file.txt destination_file.txt

确保将source_file.txt替换为要复制的源文件的路径,将destination_file.txt替换为目标文件的路径。程序将输出复制的总字节数、所用时间和复制速度(以MB/s为单位)。

要准确测试文件复制的速度,我们需要确保测试过程中尽量减少其他因素的影响,比如磁盘I/O性能、文件系统缓存、系统负载等。以下是一个更加精确的Linux C语言文件复制速度测试程序:

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <time.h>  
#include <unistd.h>  
#include <fcntl.h>  
#include <sys/stat.h>  
#include <sys/time.h>  
  
#define BUFFER_SIZE (1024 * 1024)  // 1MB 缓冲区大小  
  
void measure_time(struct timeval *start, struct timeval *end, double *elapsed_time) {  
    *end = *start;  
    gettimeofday(end, NULL);  
    *elapsed_time = (end->tv_sec - start->tv_sec) + (end->tv_usec - start->tv_usec) / 1000000.0;  
}  
  
int main(int argc, char *argv[]) {  
    if (argc != 3) {  
        fprintf(stderr, "Usage: %s source_file destination_file\n", argv[0]);  
        return 1;  
    }  
  
    const char *source_file = argv[1];  
    const char *dest_file = argv[2];  
  
    // 打开源文件和目标文件  
    int source_fd = open(source_file, O_RDONLY);  
    if (source_fd == -1) {  
        perror("Error opening source file");  
        return 1;  
    }  
  
    int dest_fd = open(dest_file, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);  
    if (dest_fd == -1) {  
        perror("Error opening destination file");  
        close(source_fd);  
        return 1;  
    }  
  
    // 获取源文件大小  
    struct stat source_stat;  
    if (fstat(source_fd, &source_stat) == -1) {  
        perror("Error getting source file size");  
        close(source_fd);  
        close(dest_fd);  
        return 1;  
    }  
    off_t file_size = source_stat.st_size;  
  
    // 分配缓冲区  
    char *buffer = (char *)malloc(BUFFER_SIZE);  
    if (!buffer) {  
        perror("Memory allocation failed");  
        close(source_fd);  
        close(dest_fd);  
        return 1;  
    }  
  
    // 初始化时间测量  
    struct timeval start_time, end_time;  
    double elapsed_time;  
    gettimeofday(&start_time, NULL);  
  
    // 文件复制循环  
    ssize_t bytes_read;  
    off_t offset = 0;  
    while ((bytes_read = pread(source_fd, buffer, BUFFER_SIZE, offset)) > 0) {  
        ssize_t bytes_written = pwrite(dest_fd, buffer, bytes_read, offset);  
        if (bytes_written != bytes_read) {  
            perror("Error writing to destination file");  
            close(source_fd);  
            close(dest_fd);  
            free(buffer);  
            return 1;  
        }  
        offset += bytes_read;  
    }  
  
    // 测量总时间  
    gettimeofday(&end_time, NULL);  
    measure_time(&start_time, &end_time, &elapsed_time);  
  
    // 计算复制速度  
    double speed = (double)file_size / elapsed_time / (1024 * 1024);  // MB/s  
  
    // 输出结果  
    printf("Copied %lld bytes in %.2f seconds. Speed: %.2f MB/s\n", (long long)file_size, elapsed_time, speed);  
  
    // 清理资源  
    free(buffer);  
    close(source_fd);  
    close(dest_fd);  
  
    return 0;  
}


在这个程序中,我们使用了pread()和pwrite()函数来进行文件的读取和写入,它们允许我们指定文件内的偏移量,这样可以避免使用fseek()和ftell(),从而提高效率。同时,我们使用gettimeofday()来测量经过的时间,它比clock()更加精确,尤其是在测量短时间间隔时。

要编译和运行此程序,请将其保存为`file_copy_speed_test.c

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

109702008

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值