@@ -267,6 +267,8 @@ where
267267 chunk_infos. sort_by_key ( |info| info. index ) ;
268268 let src_hashes = crate :: extract_hashes ( & root_map) ;
269269
270+ let mut has_initialized_file = false ;
271+
270272 for batch_start in ( 0 ..chunk_infos. len ( ) ) . step_by ( * STREAM_DECRYPT_BATCH_SIZE ) {
271273 let batch_end = ( batch_start + * STREAM_DECRYPT_BATCH_SIZE ) . min ( chunk_infos. len ( ) ) ;
272274 let batch_infos = & chunk_infos[ batch_start..batch_end] ;
@@ -288,41 +290,28 @@ where
288290 . collect :: < Vec < _ > > ( ) ;
289291
290292 // Process and write this batch immediately to disk
291- for ( i, ( info, chunk) ) in batch_infos. iter ( ) . zip ( batch_chunks. iter ( ) ) . enumerate ( ) {
293+ let mut batch_file = if !has_initialized_file {
294+ has_initialized_file = true ;
295+ OpenOptions :: new ( )
296+ . write ( true )
297+ . create ( true )
298+ . truncate ( true )
299+ . open ( output_filepath) ?
300+ } else {
301+ OpenOptions :: new ( )
302+ . append ( true )
303+ . create ( true )
304+ . open ( output_filepath) ?
305+ } ;
306+
307+ for ( info, chunk) in batch_infos. iter ( ) . zip ( batch_chunks. iter ( ) ) {
292308 let decrypted_chunk = decrypt_chunk ( info. index , & chunk. content , & src_hashes) ?;
293309
294- // For the first chunk in the entire process, create/overwrite the file
295- // For subsequent chunks, append to the file
296- if batch_start == 0 && i == 0 {
297- // First chunk: create/overwrite the file
298- let mut file = OpenOptions :: new ( )
299- . write ( true )
300- . create ( true )
301- . truncate ( true ) // Ensure we start with a clean file
302- . open ( output_filepath) ?;
303- file. write_all ( & decrypted_chunk) ?;
304- file. sync_all ( ) ?;
305- } else {
306- // Subsequent chunks: append to the file
307- append_to_file ( output_filepath, & decrypted_chunk) ?;
308- }
310+ batch_file. write_all ( & decrypted_chunk) ?;
309311 }
310- }
311312
312- Ok ( ( ) )
313- }
314-
315- /// Appends content to an existing file.
316- /// This function is memory-efficient as it doesn't keep the file handle open.
317- /// Note: This should only be used for chunks after the first one, as it appends to existing content.
318- fn append_to_file ( file_path : & Path , content : & Bytes ) -> std:: io:: Result < ( ) > {
319- let mut file = OpenOptions :: new ( )
320- . append ( true )
321- . create ( true )
322- . open ( file_path) ?;
323-
324- file. write_all ( content) ?;
325- file. sync_all ( ) ?; // Ensure data is written to disk
313+ batch_file. sync_all ( ) ?;
314+ }
326315
327316 Ok ( ( ) )
328317}
0 commit comments