快速文件复制与进度 [英] Fast file copy with progress

查看:189
本文介绍了快速文件复制与进度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为Linux编写一个SDL应用程序,它从控制台(无X服务器)工作。我有一个功能是文件复制机制,将特定文件从HDD复制到USB闪存设备,并在UI中显示此复制的进度。为了做到这一点,我使用简单的while循环和复制文件由8kB块获取副本进度。问题是,它很慢。我将在近10分钟内复制一个100 MB的文件,这是不能接受的。

I'm writing an SDL application for Linux, that works from the console (no X server). One function I have is a file copy mechanism, that copies specific files from HDD to USB Flash device, and showing progress of this copy in the UI. To do this, I'm using simple while loop and copying file by 8kB chunks to get copy progress. The problem is, that it's slow. I get to copy a 100 MB file in nearly 10 minutes, which is unacceptable.

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

How can I implement faster file copy? I was thinking about some asynchronous API that would read file from HDD to a buffer and store the data to USB in separate thread, but I don't know if I should implement this myself, because it doesn't look like an easy task. Maybe you know some C++ API/library that can that for me? Or maybe some other, better method?

推荐答案

不要使用复制进度同步更新UI,相当。您应该在主UI线程的单独线程上运行文件副本,以便文件复制可以尽可能快地进行,而不会影响应用程序的响应速度。然后,UI可以以自然率(例如以您的显示器的刷新率)更新自己。

Don't synchronously update your UI with the copy progress, that will slow things down considerably. You should run the file copy on a separate thread from the main UI thread so that the file copy can proceed as fast as possible without impeding the responsiveness of your application. Then, the UI can update itself at the natural rate (e.g. at the refresh rate of your monitor).

您还应使用比8 KB更大的缓冲区大小。实验,但我想你会得到更快的结果与更大的缓冲区大小(例如在64-128 KB范围)。

You should also use a larger buffer size than 8 KB. Experiment around, but I think you'll get faster results with larger buffer sizes (e.g. in the 64-128 KB range).

所以,它可能看起来像这样:

So, it might look something like this:

#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) 系统调用,它直接在内核空间中复制文件,当然,如果你这样做,你不能得到任何进度信息,所以这可能不总是理想的。

Note that if you are sending a file to a socket instead of another file, you should instead use the sendfile(2) system call, which copies the file directly in kernel space without round tripping into user space. Of course, if you do that, you can't get any progress information, so that may not always be ideal.

对于Windows系统,应使用 CopyFileEx code> ,这是既高效,并为您提供一个进度回调例程。

For Windows systems, you should use CopyFileEx, which is both efficient and provides you a progress callback routine.

这篇关于快速文件复制与进度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆