简体   繁体   中英

Extracted file changes Date modified

When I tried to extract my file using winrar, It retains the date modified of the file inside a .gz. But when I extracted it using a code that is working (I got from other blogs):

 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);
                }
            }
        }
    }

It changes the modified date of the extracted file to the current date which is the date and time I extracted it.

How can I able to retain the date modified of the file?

example the file in a .gz is dated as 8/13/2014 using a winrar it didn't change but when I use my code it changes to the current date I extracted it.

To be technically correct you are not extracting file but writing decompressed stream to another stream which is file in your case. After you look at it that way is obvious that last write date of file is changed.

If you want to last write time of destination file to be the same as compressed filed, you can use File.SetLastWriteTime method ( http://msdn.microsoft.com/en-US/library/system.io.file.setlastwritetime(v=vs.110).aspx ):

File.SetLastWriteTimeUtc(newFileName, fileToDecompress.LastWriteTimeUtc);

Using the .gz file's modified time is substandard, as the file has most likely been downloaded over http and may even be a stream in memory.

Following on from Mark Adler's suggestion:

    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);
    }

The modification time and date can be found in the fourth through seventh bytes of the gzip header thusly, least significant byte first:

MTIME (Modification TIME) This gives the most recent modification time of the original file being compressed. The time is in Unix format, ie, seconds since 00:00:00 GMT, Jan. 1, 1970. (Note that this may cause problems for MS-DOS and other systems that use local rather than Universal time.) If the compressed data did not come from a file, MTIME is set to the time at which compression started. MTIME = 0 means no time stamp is available.

as documented in the GZIP File Format Specification .

You can then use the other answer here to set the modify time of the file written.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM