当我尝试使用winrar提取文件时,它会在.gz中保留文件的修改日期。但是当我使用正在运行的代码(我从其他博客获得)中提取它时:
public static void Decompress(FileInfo fileToDecompress)
{
using (FileStream originalFileStream = fileToDecompress.OpenRead())
{
string currentFileName = fileToDecompress.FullName;
string date = fileToDecompress.LastWriteTimeUtc.ToString();
MessageBox.Show(date);
string newFileName = currentFileName.Remove(currentFileName.Length - fileToDecompress.Extension.Length);
using (FileStream decompressedFileStream = File.Create(newFileName))
{
using (GZipStream decompressionStream = new GZipStream(originalFileStream, CompressionMode.Decompress))
{
decompressionStream.CopyTo(decompressedFileStream);
Console.WriteLine("Decompressed: {0}", fileToDecompress.Name);
}
}
}
}
它将提取文件的修改日期更改为当前日期,即我提取它的日期和时间。
如何才能保留文件的修改日期?
示例.gz中的文件日期为2014年8月13日,使用的是winrar但没有更改,但是当我使用我的代码时,它会更改为我提取它的当前日期。
答案 0 :(得分:2)
要在技术上正确,您不是解压缩文件,而是将解压缩的流写入另一个流,这是您的案例中的文件。看一下之后,很明显文件的最后写入日期已经改变了。
如果您希望将目标文件的上次写入时间与压缩字段相同,则可以使用File.SetLastWriteTime
方法(http://msdn.microsoft.com/en-US/library/system.io.file.setlastwritetime(v=vs.110).aspx):
File.SetLastWriteTimeUtc(newFileName, fileToDecompress.LastWriteTimeUtc);
答案 1 :(得分:2)
使用.gz文件的修改时间不合标准,因为该文件很可能是通过http下载的,甚至可能是内存中的流。
继马克·阿德勒的建议之后:
using (Stream s = File.OpenRead("file.gz"))
{
uint timestamp = 0;
for (int x = 0; x < 4; x++)
s.ReadByte();
for (int x = 0; x < 4; x++)
{
timestamp += (uint)s.ReadByte() << (8*x);
}
DateTime innerFileTime = new DateTime(1970, 1, 1).AddSeconds(timestamp)
// Gzip times are stored in universal time, I actually needed two calls to get it almost right, and the time was still out by an hour
.ToLocalTime().ToLocalTime();
// Reset stream position before decompressing file
s.Seek(0, SeekOrigin.Begin);
}
答案 2 :(得分:1)
修改时间和日期可以在gzip头的第四到第七个字节中找到,因此,最低有效字节优先:
MTIME(修改时间) 这给出了原始的最近修改时间 文件被压缩。时间是Unix格式,即 自格林威治标准时间1970年1月1日00:00:00起的秒数。(注意这一点 可能会导致MS-DOS和其他使用的系统出现问题 本地而非环球时间。)如果是压缩数据 没有来自文件,MTIME被设置为时间 压缩开始了。 MTIME = 0表示没有时间戳 可用。
如GZIP File Format Specification中所述。
然后,您可以使用此处的其他答案来设置写入文件的修改时间。