@@ -267,14 +267,18 @@ protected override void CopyFileImpl(UPath srcPath, UPath destPath, bool overwri
267267 using var srcStream = srcEntry . Open ( ) ;
268268 srcStream . CopyTo ( destStream ) ;
269269 }
270- #if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
271- destEntry . ExternalAttributes = srcEntry . ExternalAttributes | ( int ) FileAttributes . Archive ;
272- #endif
270+ CopyEntryProperties ( srcEntry , destEntry , includeLastWriteTime : false ) ;
273271 TryGetDispatcher ( ) ? . RaiseCreated ( destPath ) ;
274272 }
275273
276274 /// <inheritdoc />
277275 protected override void CreateDirectoryImpl ( UPath path )
276+ {
277+ CreateDirectoryWithoutNotification ( path ) ;
278+ TryGetDispatcher ( ) ? . RaiseCreated ( path ) ;
279+ }
280+
281+ private ZipArchiveEntry CreateDirectoryWithoutNotification ( UPath path )
278282 {
279283 if ( FileExistsImpl ( path ) )
280284 {
@@ -295,8 +299,7 @@ protected override void CreateDirectoryImpl(UPath path)
295299 }
296300 }
297301
298- CreateEntry ( path , isDirectory : true ) ;
299- TryGetDispatcher ( ) ? . RaiseCreated ( path ) ;
302+ return CreateEntry ( path , isDirectory : true ) ;
300303 }
301304
302305 /// <inheritdoc />
@@ -653,28 +656,33 @@ protected override void MoveDirectoryImpl(UPath srcPath, UPath destPath)
653656 throw FileSystemExceptionHelper . NewDirectoryNotFoundException ( srcPath ) ;
654657 }
655658
656- CreateDirectoryImpl ( destPath ) ;
659+ var rootEntry = CreateDirectoryWithoutNotification ( destPath ) ;
657660 foreach ( var internalEntry in entries )
658661 {
659662 var entry = internalEntry . Entry ;
660663
664+ ZipArchiveEntry destEntry ;
665+
661666 if ( entry . FullName . Length == srcDir . Length )
662667 {
663- RemoveEntry ( entry ) ;
664- continue ;
668+ destEntry = rootEntry ;
665669 }
666-
667- var entryName = entry . FullName . Substring ( srcDir . Length ) ;
668- var isDirectory = internalEntry . IsDirectory ;
669- var destEntry = CreateEntry ( UPath . Combine ( destPath , entryName ) , isDirectory : isDirectory ) ;
670-
671- if ( ! isDirectory )
670+ else
672671 {
673- using var entryStream = entry . Open ( ) ;
674- using var destEntryStream = destEntry . Open ( ) ;
675- entryStream . CopyTo ( destEntryStream ) ;
672+ var entryName = entry . FullName . Substring ( srcDir . Length ) ;
673+ var isDirectory = internalEntry . IsDirectory ;
674+ destEntry = CreateEntry ( UPath . Combine ( destPath , entryName ) , isDirectory : isDirectory ) ;
675+
676+ if ( ! isDirectory )
677+ {
678+ using var entryStream = entry . Open ( ) ;
679+ using var destEntryStream = destEntry . Open ( ) ;
680+ entryStream . CopyTo ( destEntryStream ) ;
681+ }
676682 }
677683
684+ CopyEntryProperties ( entry , destEntry ) ;
685+
678686 TryGetDispatcher ( ) ? . RaiseCreated ( destPath ) ;
679687 RemoveEntry ( entry ) ;
680688 TryGetDispatcher ( ) ? . RaiseDeleted ( srcPath ) ;
@@ -717,6 +725,7 @@ protected override void MoveFileImpl(UPath srcPath, UPath destPath)
717725 }
718726
719727 destEntry = CreateEntry ( destPath . FullName ) ;
728+ CopyEntryProperties ( srcEntry , destEntry ) ;
720729 TryGetDispatcher ( ) ? . RaiseCreated ( destPath ) ;
721730 using ( var destStream = destEntry . Open ( ) )
722731 {
@@ -827,6 +836,7 @@ protected override void ReplaceFileImpl(UPath srcPath, UPath destPath, UPath des
827836 if ( ! destBackupPath . IsEmpty )
828837 {
829838 var destBackupEntry = CreateEntry ( destBackupPath . FullName ) ;
839+ CopyEntryProperties ( destEntry , destBackupEntry ) ;
830840 using var destBackupStream = destBackupEntry . Open ( ) ;
831841 using var destStream = destEntry . Open ( ) ;
832842 destStream . CopyTo ( destBackupStream ) ;
@@ -836,6 +846,7 @@ protected override void ReplaceFileImpl(UPath srcPath, UPath destPath, UPath des
836846 }
837847
838848 var newEntry = CreateEntry ( destPath . FullName ) ;
849+ CopyEntryProperties ( sourceEntry , newEntry ) ;
839850 using ( var newStream = newEntry . Open ( ) )
840851 {
841852 using ( var sourceStream = sourceEntry . Open ( ) )
@@ -985,11 +996,11 @@ private string GetArchivePath(UPath path, bool isDirectory)
985996 {
986997 if ( ctx . LeadingSlashInArchive )
987998 {
988- ctx . path . FullName . AsSpan ( ) . CopyTo ( span . Slice ( 0 , ctx . path . FullName . Length ) ) ;
999+ ctx . path . FullName . AsSpan ( ) . CopyTo ( span ) ;
9891000 }
9901001 else
9911002 {
992- ctx . path . FullName . AsSpan ( 1 , ctx . path . FullName . Length - 1 ) . CopyTo ( span ) ;
1003+ ctx . path . FullName . AsSpan ( 1 ) . CopyTo ( span ) ;
9931004 }
9941005
9951006 if ( ctx . isDirectory )
@@ -1003,6 +1014,21 @@ private string GetArchivePath(UPath path, bool isDirectory)
10031014
10041015 private static readonly char [ ] s_slashChars = { '/' , '\\ ' } ;
10051016
1017+ private static void CopyEntryProperties ( ZipArchiveEntry source , ZipArchiveEntry dest , bool includeLastWriteTime = true )
1018+ {
1019+ if ( includeLastWriteTime )
1020+ {
1021+ dest . LastWriteTime = source . LastWriteTime ;
1022+ }
1023+
1024+ #if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
1025+ dest . ExternalAttributes = source . ExternalAttributes ;
1026+ #endif
1027+ #if NET6_0_OR_GREATER
1028+ dest . Comment = source . Comment ;
1029+ #endif
1030+ }
1031+
10061032 private static ReadOnlySpan < char > GetName ( ZipArchiveEntry entry )
10071033 {
10081034 var name = entry . FullName . TrimEnd ( s_slashChars ) ;
0 commit comments