sharpcompress
sharpcompress copied to clipboard
can only get one entry from a zip or rar
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);
}
}
The tests have a lot of examples.
Try Disposing the entry stream. You should be putting using blocks on every stream/reader
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:
- Read the zip file once without accessing entry contents, but just adding all entry metadata to a list of
IEntry
- 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.