代码之家  ›  专栏  ›  技术社区  ›  mav

快速文件复制

  •  2
  • mav  · 技术社区  · 15 年前

    我正在为Linux编写一个SDL应用程序,它可以在控制台(no X服务器)上工作。我拥有的一个功能是文件复制机制,它将特定文件从硬盘复制到USB闪存设备,并在用户界面中显示此复制的进度。为此,我使用simple while循环并按8kB块复制文件以获得复制进度。问题是,它太慢了。我可以在近10分钟内复制一个100 MB的文件,这是不可接受的。

    如何实现更快的文件复制?我在考虑一些异步API,它可以将文件从HDD读取到缓冲区,并将数据存储到单独的线程中的USB,但我不知道是否应该自己实现,因为这看起来不是一个简单的任务。也许你知道一些C++ API /库,可以为我吗?或者其他更好的方法?

    2 回复  |  直到 15 年前
        1
  •  5
  •   Karsten Koop    7 年前

    不要用复制进度同步更新用户界面,这样会大大降低速度。您应该在主UI线程之外的单独线程上运行文件副本,以便文件副本可以尽可能快地进行,而不会妨碍应用程序的响应。然后,UI可以以自然的速率(例如,以监视器的刷新率)更新自己。

    您还应该使用大于8KB的缓冲区。尝试一下,但我认为使用较大的缓冲区大小(例如,在64-128 KB的范围内)可以获得更快的结果。

    可能是这样的:

    #define BUFSIZE (64*1024)
    
    volatile off_t progress, max_progress;
    
    void *thread_proc(void *arg)
    {
        // Error checking omitted for expository purposes
        char buffer[BUFSIZE];
        int in = open("source_file", O_RDONLY);
        int out = open("destination_file", O_WRONLY | O_CREAT | O_TRUNC);
    
        // Get the input file size
        struct stat st;
        fstat(in, &st);
    
        progress = 0;
        max_progress = st.st_size;
    
        ssize_t bytes_read;
        while((bytes_read = read(in, buffer, BUFSIZE)) > 0)
        {
            write(out, buffer, BUFSIZE);
            progress += bytes_read;
        }
    
        // copy is done, or an error occurred
        close(in);
        close(out);
    
        return 0;
    }
    
    void start_file_copy()
    {
        pthread_t t;
        pthread_create(&t, NULL, &thread_proc, 0);
    }
    
    // In your UI thread's repaint handler, use the values of progress and
    // max_progress
    

    请注意,如果要将文件发送到 插座 您应该使用 sendfile(2) 系统调用,它直接在内核空间复制文件,而不必往返到用户空间。当然,如果你这样做了,你就不能得到任何进展信息,所以这可能并不总是理想的。

    对于Windows系统,您应该使用 CopyFileEx ,它既高效又为您提供了进度回调例程。

        2
  •  4
  •   Amirshk    15 年前

    让操作系统完成所有工作:

    1. 将文件映射到内存: mmap ,将大大加快读取过程。
    2. 使用保存到文件 msync .