描述here如何压缩文件,但该文件已经存在。
我稍微调整了一下,所以我现在尝试在创建文件流后立即创建一个文件上设置了NTFS压缩属性的文件,然后将数据添加到文件中。
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Diagnostics;
namespace Compress {
class Program {
[DllImport("kernel32.dll")]
public static extern int DeviceIoControl(IntPtr hDevice, int
dwIoControlCode, ref short lpInBuffer, int nInBufferSize, IntPtr
lpOutBuffer, int nOutBufferSize, ref int lpBytesReturned, IntPtr
lpOverlapped);
static void Main(string[] args) {
string fileName = @"D:\temp\t.txt";
int lpBytesReturned = 0;
int FSCTL_SET_COMPRESSION = 0x9C040;
short COMPRESSION_FORMAT_DEFAULT = 1;
byte[] data = new byte[4096];
for (int i = 0; i < 4096; i++) {
data[i] = 42;
}
Stopwatch timer = Stopwatch.StartNew();
FileStream f = File.Open(fileName, System.IO.FileMode.OpenOrCreate,
System.IO.FileAccess.ReadWrite, System.IO.FileShare.None);
int result = DeviceIoControl(f.Handle, FSCTL_SET_COMPRESSION,
ref COMPRESSION_FORMAT_DEFAULT, 2 /*sizeof(short)*/, IntPtr.Zero, 0,
ref lpBytesReturned, IntPtr.Zero);
for (int i = 0; i < 100000; i++) {
f.Write(data, 0, data.Length);
}
f.Close();
timer.Stop();
Console.WriteLine("Time to write file = " + timer.ElapsedMilliseconds);
}
}
}
所以,我每次都在写大约4KB的数据。在我的系统上,这需要大约650毫秒。如果我删除了DeviceIoControl函数调用并运行相同的测试,那么它会快一点并且运行大约550毫秒(平均几次运行)。
根据this blog,我希望压缩会创建更少量的数据进行存储。
NTFS通过将数据流划分为CU来压缩文件(这类似于稀疏文件的工作方式)。当创建或改变流内容时,数据流中的每个CU被单独压缩。如果压缩导致一个或多个集群减少,则压缩单元将以其压缩格式写入磁盘。
几个问题:
什么可以解释我通过NTFS压缩存储数据时的时间增加?我没有注意到两次测试运行之间的CPU使用率(通过任务管理器)发生了实质性变化(两种情况下CPU稳定在5%)
压缩量也很小,文件大小为390MB,但磁盘大小只减少到259MB。考虑到数据是完全冗余的,为什么压缩量如此之低?
答案 0 :(得分:0)
我无法确定你到底在做什么,但听起来你正在追加一个现有的压缩文件,一次4K。最重要的是,如果你只是让压缩机4K工作,你就不能期望太多的压缩。压缩取决于要压缩的历史和统计数据,并且需要的不仅仅是利用重复字符串和偏置频率分布。
如果您一次编写整个文件,您可能会看到更有效的压缩。
答案 1 :(得分:0)
我认为您的测试有点混乱 - 如果您想要可重复的结果,请使用FileMode.Create并让它每次都重建该文件。就目前而言,您在每次运行时都会添加到文件中。谁知道你有多少运行数据:-) FileMode.Create将创建该文件,或截断它(如果它存在)。我敢打赌,在您修复之后,您的压缩比会更合理。
压缩开销需要时间 - 即使数据非常流畅。你的数字对我来说看起来很合理 - CPU似乎永远不会被赋予任务,因为它正在做着“艰苦的工作”#34;每次同步 I / O请求只能压缩一次 - 因此CPU增加的开销根本不会使仪表倾斜很多 - 因为它在大多数I / O作业中展开。
此外 - NTFS压缩导致文件非常碎片 - 对于大文件尤其如此 - 并且不推荐使用。你最终得到一个类似稀疏的文件......一个会报告比实际用于存储文件的空间更多的文件。操作系统可以将类似稀疏的群集用于其他文件 - 但是大小报告会混乱。查看this维基百科文章(在文件压缩标题下)。