@@ -17,22 +17,24 @@ namespace AsyncToSyncCodeRoundtripSynchroniserMonitor
1717{
1818 public static partial class FileExtensions
1919 {
20+ public static int MaxByteArraySize = 0x7FFFFFC7 ; //https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/runtime/gcallowverylargeobjects-element?redirectedfrom=MSDN#remarks
21+
2022 //https://stackoverflow.com/questions/18472867/checking-equality-for-two-byte-arrays/
2123 public static bool BinaryEqual ( Binary a , Binary b )
2224 {
2325 return a . Equals ( b ) ;
2426 }
2527
26- public static async Task < byte [ ] > ReadAllBytesAsync ( string path , CancellationToken cancellationToken = default ( CancellationToken ) )
28+ public static async Task < Tuple < byte [ ] , long > > ReadAllBytesAsync ( string path , CancellationToken cancellationToken = default ( CancellationToken ) , long maxFileSize = 0 )
2729 {
2830 while ( true )
2931 {
3032 if ( cancellationToken . IsCancellationRequested )
31- return await Task . FromCanceled < byte [ ] > ( cancellationToken ) ;
33+ return await Task . FromCanceled < Tuple < byte [ ] , long > > ( cancellationToken ) ;
3234
3335 try
3436 {
35- using ( FileStream stream = new FileStream (
37+ using ( var stream = new FileStream (
3638 path ,
3739 FileMode . Open ,
3840 FileAccess . Read ,
@@ -41,10 +43,17 @@ public static bool BinaryEqual(Binary a, Binary b)
4143 useAsync : true
4244 ) )
4345 {
44- var len = ( int ) stream . Length ; //NB! the lenght might change during the code execution, so need to save it into separate variable
46+ long len = stream . Length ; //NB! the length might change during the code execution, so need to save it into separate variable
47+
48+ maxFileSize = Math . Min ( MaxByteArraySize , maxFileSize ) ;
49+ if ( maxFileSize > 0 && len > maxFileSize )
50+ {
51+ return new Tuple < byte [ ] , long > ( null , len ) ;
52+ }
53+
4554 byte [ ] result = new byte [ len ] ;
46- await stream . ReadAsync ( result , 0 , len , cancellationToken ) ;
47- return result ;
55+ await stream . ReadAsync ( result , 0 , ( int ) len , cancellationToken ) ;
56+ return new Tuple < byte [ ] , long > ( result , len ) ;
4857 }
4958 }
5059 catch ( IOException )
@@ -61,21 +70,21 @@ public static bool BinaryEqual(Binary a, Binary b)
6170 catch ( TaskCanceledException )
6271 {
6372 //do nothing here
64- return await Task . FromCanceled < byte [ ] > ( cancellationToken ) ;
73+ return await Task . FromCanceled < Tuple < byte [ ] , long > > ( cancellationToken ) ;
6574 }
6675 }
6776 }
6877 }
6978
70- public static async Task WriteAllBytesAsync ( string path , byte [ ] contents , CancellationToken cancellationToken = default ( CancellationToken ) )
79+ public static async Task WriteAllBytesAsync ( string path , byte [ ] contents , CancellationToken cancellationToken = default ( CancellationToken ) , int writeBufferKB = 0 , int bufferWriteDelayMs = 0 )
7180 {
7281 while ( true )
7382 {
7483 cancellationToken . ThrowIfCancellationRequested ( ) ;
7584
7685 try
7786 {
78- using ( FileStream stream = new FileStream (
87+ using ( var stream = new FileStream (
7988 path ,
8089 FileMode . OpenOrCreate ,
8190 FileAccess . Write ,
@@ -84,7 +93,24 @@ public static bool BinaryEqual(Binary a, Binary b)
8493 useAsync : true
8594 ) )
8695 {
87- await stream . WriteAsync ( contents , 0 , contents . Length , cancellationToken ) ;
96+ var writeBufferLength = writeBufferKB * 1024 ;
97+ if ( writeBufferLength <= 0 || bufferWriteDelayMs <= 0 ) //NB! disable write buffer length limit if delay is 0
98+ writeBufferLength = contents . Length ;
99+
100+ for ( int i = 0 ; i < contents . Length ; i += writeBufferLength )
101+ {
102+ if ( i > 0 && bufferWriteDelayMs > 0 )
103+ {
104+ #if ! NOASYNC
105+ await Task . Delay ( bufferWriteDelayMs , cancellationToken ) ;
106+ #else
107+ cancellationToken . WaitHandle . WaitOne ( bufferWriteDelayMs ) ;
108+ #endif
109+ }
110+
111+ await stream . WriteAsync ( contents , i , writeBufferLength , cancellationToken ) ;
112+ }
113+
88114 return ;
89115 }
90116 }
0 commit comments