Warum liest ZipArchiveEntry.Open().ReadAsync(...) weniger Bytes als ZipArchiveEntry.Open().Stream.Read(...)?C#

Ein Treffpunkt für C#-Programmierer
Guest
 Warum liest ZipArchiveEntry.Open().ReadAsync(...) weniger Bytes als ZipArchiveEntry.Open().Stream.Read(...)?

Post by Guest »

Dies ist bei einem 400-MB-Archiv innerhalb von Sekunden abgeschlossen.

Code: Select all

private static async Task ExtractFilesAsync(this ZipArchive archive, string destination, IProgress progress = null)
{
await Task.Run(() =>
{
long bytesWritten = 0;
long totalBytes = archive.GetUncompressedSize();
int percent = 0;
foreach (ZipArchiveEntry entry in archive.Entries)
{
if (!entry.IsDirectory())
{
string fullPath = Path.Combine(destination, entry.FullName);

using (FileStream writeStream = File.OpenWrite(fullPath))
{
using (Stream readStream = entry.Open())
{
int chunkSize = 1024;
byte[] buffer = new byte[chunkSize];

while (true)
{
int bytesRead = readStream.Read(buffer, 0, chunkSize);
if (bytesRead == 0)
{
break;
}
writeStream.Write(buffer, 0, bytesRead);
bytesWritten += bytesRead;
int newPercent = (int)(bytesWritten / (double)totalBytes * 100.0);
if (newPercent > percent)
{
percent = newPercent;
progress?.Report(percent);
Trace.WriteLine($"{percent}");
}
}
}
}
}
}
});
}
Aber wenn ich die asynchrone Version von Stream.Read / Write verwende, dauert es ungefähr eine Minute.

Code: Select all

private static async Task ExtractFilesAsync(this ZipArchive archive, string destination, IProgress progress = null)
{
long bytesWritten = 0;
long totalBytes = archive.GetUncompressedSize();
int percent = 0;
foreach (ZipArchiveEntry entry in archive.Entries)
{
if (!entry.IsDirectory())
{
string fullPath = Path.Combine(destination, entry.FullName);

using (FileStream writeStream = File.OpenWrite(fullPath))
{
using (Stream readStream = entry.Open())
{
int chunkSize = 1024;
byte[] buffer = new byte[chunkSize];

while (true)
{
int bytesRead = await readStream.ReadAsync(buffer, 0, chunkSize);
if (bytesRead == 0)
{
break;
}
await writeStream.WriteAsync(buffer, 0, bytesRead);
bytesWritten += bytesRead;
int newPercent = (int)(bytesWritten / (double)totalBytes * 100.0);
if (newPercent > percent)
{
percent = newPercent;
progress?.Report(percent);
Trace.WriteLine($"{percent}");
}
}
}
}
}
}

}
Warum ist das so?
Bearbeiten:
ChunkSize wurde auf 1 MB erhöht.
Es sieht so aus, als ob Stream.ReadAsync nur etwa 15 kB pro Lesevorgang liest, während Stream.Read die gesamten MB liest. Daher ist Stream.ReadAsync der Engpass. Aber warum?

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post