【问题标题】:Extracted file changes Date modified提取的文件更改 修改日期
【发布时间】:2014-08-19 03:47:38
【问题描述】:

当我尝试使用 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 中的文件使用 winrar 的日期为 2014 年 8 月 13 日,它没有更改,但是当我使用我的代码时,它会更改为我提取它的当前日期。

【问题讨论】:

    标签: c# gzip gzipstream


    【解决方案1】:

    从技术上讲,您不是在提取文件,而是将解压缩的流写入另一个流,在您的情况下是文件。在您以这种方式查看之后,很明显文件的最后写入日期已更改。

    如果希望目标文件的最后写入时间与压缩文件相同,可以使用File.SetLastWriteTime方法(http://msdn.microsoft.com/en-US/library/system.io.file.setlastwritetime(v=vs.110).aspx):

    File.SetLastWriteTimeUtc(newFileName, fileToDecompress.LastWriteTimeUtc);
    

    【讨论】:

    • 我已经对我的代码做到了这一点。而且我知道我正在编写/创建新文件。不管怎么说,还是要谢谢你。我真正想知道的是如何才能获得 .gz 文件中的文件日期,因为在某些情况下,.gz 修改日期与其中文件的修改日期不同,我发现它不可能我的代码。
    • 我得到的和你告诉我的一样。我的 fileToDecompress 的 LastWriteTime。
    • 我也发现,或者可能有,但我不打算在我的应用程序中使用第三方,我的代码是我能够解压缩 .gz 文件的唯一方法。这就是为什么由于我的代码所做的事情,我真的无法获得其中文件的修改日期。
    • 如果要从 Gzip 文件中读取元数据,可以使用 SharpZipLib (icsharpcode.github.io/SharpZipLib) 库
    【解决方案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);
        }
    

    【讨论】:

    • new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(timestamp) 将解决您的两次通话问题。您需要创建一个 UTC 时间对象,然后添加秒。
    【解决方案3】:

    因此修改时间和日期可以在gzip头的第四到第七个字节中找到,最低有效字节在前:

    MTIME(修改时间) 这给出了原始文件的最新修改时间 正在压缩的文件。时间采用 Unix 格式,即 自 1970 年 1 月 1 日格林威治标准时间 00:00:00 以来的秒数。(请注意,这 可能会导致 MS-DOS 和其他使用 本地时间而不是世界标准时间。)如果压缩数据 不是来自文件,MTIME 设置为 压缩开始。 MTIME = 0 表示没有时间戳 可用。

    GZIP File Format Specification 中所述。

    然后您可以使用此处的其他答案来设置写入文件的修改时间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-17
      • 1970-01-01
      • 2013-01-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多