.tmp file - quick question (ZIP)

Aug 12, 2011 at 4:26 PM

Hi,

I am using latest build and using the Zip Class.

I did not test this further yet, but I will:

When i'm unzipping a file and the folder already contains a file called

filename.tmp

the unzip just fails with an error, that the file already exists.

(for example: i extract the test.txt to the folder TestFolder and in that folder there is a file called test.txt.tmp)

So would it be good to check the folder, to where I extract files, for .tmp files and delete them?

Or is there any other way?

Another Question would be: from what i understand of that, i could never zip a filename.tmp or unzip it right?

Thanks for your help.

Coordinator
Aug 14, 2011 at 12:57 AM
Edited Aug 14, 2011 at 1:42 PM

I think your characterization of the situation is not quite right. 

When i'm unzipping a file and the folder already contains a file called "filename.tmp" the unzip just fails with an error, that the file already exists.

The way you've described the situation, it is specific to a particular filename.  This is untrue, I think.  On the other hand, the ZipFile class will not overwrite existing files during extraction, unless you specifically ask it to.  there is a property called ExtractExistingFileAction, which tells the class what to do when extraction would overwrite an existing file.

 >  i could never zip a filename.tmp or unzip it right?

I don't think that is correct.  If you have a test case that exhibits this behavior, please post the code.

 

Aug 15, 2011 at 5:56 PM
Edited Aug 15, 2011 at 6:05 PM

Ok let me try to explain it better.

I zip the folder C:\Test\ which contains:
helloworld.txt
test.txt

now i zip it with the following code (real code is more complicated, but to get you an idea of what I use):

using (ZipFile zip = new ZipFile())
{
  zip.CompressionLevel = Ionic.Zlib.CompressionLevel.Level5
  //zip.ProvisionalAlternateEncoding = Encoding.UTF8;
  zip.AlternateEncoding = Encoding.UTF8;
  zip.AlternateEncodingUsage = ZipOption.AsNecessary;
  zip.UseZip64WhenSaving = Zip64Option.AsNecessary;
  zip.AddItem("C:\Test\","");
  zip.Save("C:\Test.zip");
}

Unzip the zipfile with the following code:

ZipFile zip = ZipFile.Read("C:\Test.zip");
foreach (ZipEntry ze in zip)
{
        ze.ExtractExistingFile = ExtractExistingFileAction.OverwriteSilently;
        ze.Extract("C:\Test\");
}

 

What happens now is, for each file in the zipfile the library creates a filename.ext.tmp while he unpacks the specific file of the ze.Extract.
That means, when it extracts helloworld.txt on ze.Extract(...); in the folder c:\test\ there will be a file called helloworld.txt.tmp till extract finishes (use big files to test).

I think that this is no problem at all, but, when C:\test already has a file called helloworld.txt.tmp and i try to extract helloworld.txt in that folder, the library just fails with the message, that the file already exists (the helloworld.txt.tmp, not the helloworld.txt).

 

Normaly this never happens, but when i unpack a zipfile to a folder and a file in that zipfile fails to extract (for example crc check fails), then the library creates the .tmp file while extracting, fails to extract with an error (crc check) and leaves the .tmp there. When I extract again now, the library tells me that the .tmp file already exists and fails again.

 

The ExtractExistingFileAction.OverwriteSilently does not apply for that .tmp files and the zip.TempFileFolder is just used for zip.save() but not for extraction (i tried to do a workaround with a tmp folder which i always clear before extracting something).

So far... I'm still working on this. I think I need to clear all .tmp files of the folders to which I will extract stuff (Wanted to avoid that solution, since I dont know if that folder does not need those .tmp files for something else).

Coordinator
Aug 15, 2011 at 8:29 PM

yes, I see now.

A very clear explanation.  I see that you are correct, and this is a problem. Actually 2 problems:

  1. The temporary filename used by dotnetzip could clash with an existing file in the folder.
  2. the temporary file remains after a failed extraction

I can correct the first problem. 

But the second problem - can you provide some code that causes this scenario? 

 

Coordinator
Aug 15, 2011 at 8:31 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Aug 16, 2011 at 2:10 AM

For the second problem, what you need is an faulty/broken zip, which is ok to read, but fails to extract one or more files (one is enough). I can not produce a zip file like that at the moment (no idea how) and i can't send you the one i actually have, cause it's a sensitive file of a customer.

The easiest broken file would be a zip file which has a wrong CRC code for one of the files it contains. I'll try to produce a zip file like that later if I can (or something similar).

Aug 16, 2011 at 7:15 AM

The code sample in this work item produces a zip with an invalid CRC:

http://dotnetzip.codeplex.com/workitem/14087

Might help reproduce the *.tmp file issue above.

Aug 16, 2011 at 11:48 AM
Edited Aug 16, 2011 at 11:54 AM

Thanks for you code sample pointy.

I got through this now... this was more complicated then i thought, cause the filename.ext.tmp file only exists after extraction fails when the filename.ext exists prior to extraction.

Here is a working code sample to fully reproduce the problem (delete content of C:\test\ before you start it):

 

      String faultstring = new String(' ', 2490368);
      string okstring = "Hello World!";

      try
      {
        System.IO.Directory.CreateDirectory("C:\\Test");
        System.IO.Directory.CreateDirectory("C:\\Test\\Test");

        System.IO.File.WriteAllText("C:\\Test\\test.txt", faultstring);
        System.IO.File.WriteAllText("C:\\Test\\hello.txt", okstring);
        // comment the next two lines out to have no test.txt.tmp:
        System.IO.File.Copy("C:\\Test\\test.txt", "C:\\Test\\Test\\test.txt", true);
        System.IO.File.Copy("C:\\Test\\hello.txt", "C:\\Test\\Test\\hello.txt", true);
        MessageBox.Show("files created...");
      }
      catch (Exception ex)
      {
        MessageBox.Show(ex.Message);
      }

      try
      {
        using (ZipFile zip = new ZipFile())
        {
          zip.CompressionLevel = Ionic.Zlib.CompressionLevel.Level5;
          zip.AlternateEncoding = Encoding.UTF8;
          zip.AlternateEncodingUsage = ZipOption.AsNecessary;
          zip.UseZip64WhenSaving = Zip64Option.AsNecessary;

          zip.AddFile("C:\\Test\\hello.txt", "");
          zip.AddFile("C:\\Test\\test.txt", "");
          zip.Save("C:\\Test\\test.zip");
          MessageBox.Show("zip created...");
        }
      }
      catch (Exception ex)
      {
        MessageBox.Show(ex.Message);
      }

      try
      {
        using (ZipFile zip = ZipFile.Read("C:\\Test\\test.zip"))
        {
          foreach (ZipEntry ze in zip)
          {
            ze.ExtractExistingFile = ExtractExistingFileAction.OverwriteSilently;
            ze.Extract("C:\\Test\\Test");
          }
        }
        MessageBox.Show("zip extracted...");
      }
      catch (Exception ex)
      {
        MessageBox.Show(ex.Message);
      }


If you don't out comment the two lines in the code (mentioned), then u will now have a file C:\Test\Test\test.txt.tmp

Regards,
DexMiK

Jul 31, 2012 at 6:09 PM

Hello,

I'm also running into this behavior. Are there any plans to update the code for this any time soon? Why not just create a .tmp file in a temp directory...?

Mar 28, 2013 at 3:50 AM
Edited Mar 28, 2013 at 3:51 AM
Same problem here. March, 2013.

The only workaround right now is to recursively delete *.tmp before unzipping.
myOutputDirectory.GetFiles("*.tmp", SearchOption.AllDirectories).ToList().ForEach(file=>file.Delete());
Léon Pelletier
Jul 31, 2013 at 5:23 AM
Edited Jul 31, 2013 at 5:59 AM
I have the same problem, in the latest version (currently 1.9.1.8 ~2011)

What could be the reason for saving temp files not into the system temp directory by default?

Looks like we can do this by doing:
using (var zip = new ZipFile(zipfileName)) { zip.TempFileFolder = Path.GetTempPath();...