Use a consistent buffer size when writing out zip files (#5570)

This commit is contained in:
Charlie Marsh 2024-07-29 14:45:33 -04:00 committed by GitHub
parent 05b1f51aa1
commit f70501a22e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 15 additions and 8 deletions

View file

@ -45,12 +45,12 @@ pub async fn unzip<R: tokio::io::AsyncRead + Unpin>(
// We don't know the file permissions here, because we haven't seen the central directory yet. // We don't know the file permissions here, because we haven't seen the central directory yet.
let file = fs_err::tokio::File::create(&path).await?; let file = fs_err::tokio::File::create(&path).await?;
let mut writer = let size = entry.reader().entry().uncompressed_size();
if let Ok(size) = usize::try_from(entry.reader().entry().uncompressed_size()) { let mut writer = if let Ok(size) = usize::try_from(size) {
tokio::io::BufWriter::with_capacity(size, file) tokio::io::BufWriter::with_capacity(std::cmp::min(size, 1024 * 1024), file)
} else { } else {
tokio::io::BufWriter::new(file) tokio::io::BufWriter::new(file)
}; };
let mut reader = entry.reader_mut().compat(); let mut reader = entry.reader_mut().compat();
tokio::io::copy(&mut reader, &mut writer).await?; tokio::io::copy(&mut reader, &mut writer).await?;
} }

View file

@ -14,6 +14,7 @@ pub fn unzip<R: Send + std::io::Read + std::io::Seek + HasLength>(
target: &Path, target: &Path,
) -> Result<(), Error> { ) -> Result<(), Error> {
// Unzip in parallel. // Unzip in parallel.
let reader = std::io::BufReader::new(reader);
let archive = ZipArchive::new(CloneableSeekableReader::new(reader))?; let archive = ZipArchive::new(CloneableSeekableReader::new(reader))?;
let directories = Mutex::new(FxHashSet::default()); let directories = Mutex::new(FxHashSet::default());
(0..archive.len()) (0..archive.len())
@ -45,8 +46,14 @@ pub fn unzip<R: Send + std::io::Read + std::io::Seek + HasLength>(
} }
// Copy the file contents. // Copy the file contents.
let mut outfile = fs_err::File::create(&path)?; let outfile = fs_err::File::create(&path)?;
std::io::copy(&mut file, &mut outfile)?; let size = file.size();
let mut writer = if let Ok(size) = usize::try_from(size) {
std::io::BufWriter::with_capacity(std::cmp::min(size, 1024 * 1024), outfile)
} else {
std::io::BufWriter::new(outfile)
};
std::io::copy(&mut file, &mut writer)?;
// See `uv_extract::stream::unzip`. For simplicity, this is identical with the code there except for being // See `uv_extract::stream::unzip`. For simplicity, this is identical with the code there except for being
// sync. // sync.