c# - 如何高效分割大文件

标签 c# .net

我想知道如何在不使用太多系统资源的情况下拆分大文件。 我目前正在使用此代码:

public static void SplitFile(string inputFile, int chunkSize, string path)
{
    byte[] buffer = new byte[chunkSize];

    using (Stream input = File.OpenRead(inputFile))
    {
        int index = 0;
        while (input.Position < input.Length)
        {
            using (Stream output = File.Create(path + "\\" + index))
            {
                int chunkBytesRead = 0;
                while (chunkBytesRead < chunkSize)
                {
                    int bytesRead = input.Read(buffer, 
                                               chunkBytesRead, 
                                               chunkSize - chunkBytesRead);

                    if (bytesRead == 0)
                    {
                        break;
                    }
                    chunkBytesRead += bytesRead;
                }
                output.Write(buffer, 0, chunkBytesRead);
            }
            index++;
        }
    }
}

将 1.6GB 文件拆分为 14mb 文件的操作需要 52.370 秒。我不关心操作需要多长时间,我更关心的是使用的系统资源,因为此应用程序将部署到共享托管环境。目前,此操作使我的系统 HDD IO 使用率达到 100%,并且大大降低了我的系统速度。 CPU使用率低; RAM 增加了一点,但看起来还不错。

有什么方法可以限制此操作使用过多资源?

谢谢

最佳答案

在内存中组装每个输出文件似乎很奇怪;我怀疑您应该运行一个内部缓冲区(可能是 20k 左右)并更频繁地调用 Write

最终,如果你需要 IO,你就需要 IO。如果您想礼貌地使用共享托管环境,您可以添加有意的停顿 - 可能在内循环中的短暂停顿,以及外循环中较长的停顿(可能是 1 秒)。这不会对您的整体时间产生太大影响,但可能有助于其他进程获得一些 IO。

内部循环的缓冲区示例:

public static void SplitFile(string inputFile, int chunkSize, string path)
{
    const int BUFFER_SIZE = 20 * 1024;
    byte[] buffer = new byte[BUFFER_SIZE];

    using (Stream input = File.OpenRead(inputFile))
    {
        int index = 0;
        while (input.Position < input.Length)
        {
            using (Stream output = File.Create(path + "\\" + index))
            {
                int remaining = chunkSize, bytesRead;
                while (remaining > 0 && (bytesRead = input.Read(buffer, 0,
                        Math.Min(remaining, BUFFER_SIZE))) > 0)
                {
                    output.Write(buffer, 0, bytesRead);
                    remaining -= bytesRead;
                }
            }
            index++;
            Thread.Sleep(500); // experimental; perhaps try it
        }
    }
}

关于c# - 如何高效分割大文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3967541/

相关文章:

c# - 同时请求多个请求的静态成员和实例方法

c# - Winform 变量作用域

c# - 当属性更改时重新启动可观察订阅

c# - UseCompatibleTextRendering 属性在设置为 false 时不是由设计器创建的

C#检查xml文件中的元素

c# - 从 C# 调用 python 代码(.py 文件)

c# - 对象未设置为对象的实例

c# - 有没有办法在指定线程上执行回调?

.net - 在WCF中使用KnownType和ServiceKnownType有什么区别?

.net - 如何将 DateTimeOffset 参数传递给 oData 函数