can only get one entry from a zip or rar #398

Open
opened 2026-01-29 22:11:16 +00:00 by claunia · 2 comments
Owner

Originally created by @AnakinSkyCN on GitHub (May 22, 2020).

Hi,

I've tried using MoveToNextEntry to enumerate all the entries in a zip or rar with multiple entries, but it only return one entry then ended.

did I do something wrong?

            using (Stream stream = File.OpenRead(archivefile))
           {
                IReader reader = ReaderFactory.Open(stream);
                try
                {
                    while (reader.MoveToNextEntry())
                    {
                        if (!reader.Entry.IsDirectory)
                        {
                            Console.WriteLine(reader.Entry.Key);
                            EntryStream entryStream = reader.OpenEntryStream();
                            DataSetSampleCase.dtSampleCaseFileRow newrow = dsSampleCase.dtSampleCaseFile.NewdtSampleCaseFileRow();
                            newrow.完整文件路径 = archivefile + @"\\" +  reader.Entry.Key;
                            string purefilename = Func.StringOP.PureFileNameFromFull(reader.Entry.Key);
                            newrow.文件 = purefilename;
                            newrow.时间 = File.GetLastWriteTime(archivefile);
                            string Content = IOFunc.ContentByFileName(reader.Entry.Key);
                            newrow.内容 = Content;
                            dsSampleCase.dtSampleCaseFile.AdddtSampleCaseFileRow(newrow);
                        }
                    }
                }
                catch (Exception err)
                {
                    Debug.WriteLine(err.Message);
                }
            }
Originally created by @AnakinSkyCN on GitHub (May 22, 2020). Hi, I've tried using MoveToNextEntry to enumerate all the entries in a zip or rar with multiple entries, but it only return one entry then ended. did I do something wrong? ``` using (Stream stream = File.OpenRead(archivefile)) { IReader reader = ReaderFactory.Open(stream); try { while (reader.MoveToNextEntry()) { if (!reader.Entry.IsDirectory) { Console.WriteLine(reader.Entry.Key); EntryStream entryStream = reader.OpenEntryStream(); DataSetSampleCase.dtSampleCaseFileRow newrow = dsSampleCase.dtSampleCaseFile.NewdtSampleCaseFileRow(); newrow.完整文件路径 = archivefile + @"\\" + reader.Entry.Key; string purefilename = Func.StringOP.PureFileNameFromFull(reader.Entry.Key); newrow.文件 = purefilename; newrow.时间 = File.GetLastWriteTime(archivefile); string Content = IOFunc.ContentByFileName(reader.Entry.Key); newrow.内容 = Content; dsSampleCase.dtSampleCaseFile.AdddtSampleCaseFileRow(newrow); } } } catch (Exception err) { Debug.WriteLine(err.Message); } } ```
claunia added the question label 2026-01-29 22:11:16 +00:00
Author
Owner

@adamhathcock commented on GitHub (May 24, 2020):

The tests have a lot of examples.

Try Disposing the entry stream. You should be putting using blocks on every stream/reader

@adamhathcock commented on GitHub (May 24, 2020): The tests have a lot of examples. Try Disposing the entry stream. You should be putting using blocks on every stream/reader
Author
Owner

@hungyiloo commented on GitHub (Apr 13, 2021):

I'm running into this too. It happens even with using (var entryStream = reader.OpenEntryStream()) to properly dispose it.

using (var zipReader = ReaderFactory.Open(fileStream, new ReaderOptions { Password = privateKey }))
{
    while (zipReader.MoveToNextEntry())
    {
        Console.WriteLine(zipReader.Entry.Key);

        // commenting out the next two lines of code will make the Console.WriteLine above print out ALL entries
        // but leaving them in will make it print only one line.
        using (var entryStream = zipReader.OpenEntryStream())
        using (var streamReader = new StreamReader(entryStream, Encoding.UTF8))
        {
            //...other logic. This block could be empty and still exhibits the issue.
        }
    }
}

Seems to only happen with certain zip files, but unfortunately I'm dealing with data that I can't publish so I can't provide a test case. The affected files I have are password protected. It skips files only when the entry content is accessed via methods like OpenEntryStream() or WriteEntryTo(memStream). If the entry contents is not accessed using those methods, no entries are skipped and the MoveToNextEntry() behavior works perfectly.

Since my zip files were small, I got around this issue with a really dirty and poor performing hack:

  1. Read the zip file once without accessing entry contents, but just adding all entry metadata to a list of IEntry
  2. Recreate the zip reader to read each IEntry's contents, skipping all other entries except the one, matching by IEntry.Key. A fresh zip reader needs to be created for each entry whose contents needs to be read.
@hungyiloo commented on GitHub (Apr 13, 2021): I'm running into this too. It happens even with `using (var entryStream = reader.OpenEntryStream())` to properly dispose it. ``` using (var zipReader = ReaderFactory.Open(fileStream, new ReaderOptions { Password = privateKey })) { while (zipReader.MoveToNextEntry()) { Console.WriteLine(zipReader.Entry.Key); // commenting out the next two lines of code will make the Console.WriteLine above print out ALL entries // but leaving them in will make it print only one line. using (var entryStream = zipReader.OpenEntryStream()) using (var streamReader = new StreamReader(entryStream, Encoding.UTF8)) { //...other logic. This block could be empty and still exhibits the issue. } } } ``` Seems to only happen with certain zip files, but unfortunately I'm dealing with data that I can't publish so I can't provide a test case. The affected files I have are password protected. It skips files only when the entry content is accessed via methods like `OpenEntryStream()` or `WriteEntryTo(memStream)`. If the entry contents is *not* accessed using those methods, *no entries are skipped* and the `MoveToNextEntry()` behavior works perfectly. Since my zip files were small, I got around this issue with a really dirty and poor performing hack: 1. Read the zip file once without accessing entry contents, but just adding all entry metadata to a list of `IEntry` 2. Recreate the zip reader to read each IEntry's contents, skipping all other entries except the one, matching by `IEntry.Key`. A fresh zip reader needs to be created for each entry whose contents needs to be read.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/sharpcompress#398