@@ -16,6 +16,9 @@ import '../base/utils.dart';
16
16
import '../convert.dart' ;
17
17
import 'build_system.dart' ;
18
18
19
+ /// The default threshold for file chunking is 250 KB, or about the size of `framework.dart` .
20
+ const int kDefaultFileChunkThresholdBytes = 250000 ;
21
+
19
22
/// An encoded representation of all file hashes.
20
23
class FileStorage {
21
24
FileStorage (this .version, this .files);
@@ -91,13 +94,16 @@ class FileStore {
91
94
@required File cacheFile,
92
95
@required Logger logger,
93
96
FileStoreStrategy strategy = FileStoreStrategy .hash,
97
+ int fileChunkThreshold = kDefaultFileChunkThresholdBytes,
94
98
}) : _logger = logger,
95
99
_strategy = strategy,
96
- _cacheFile = cacheFile;
100
+ _cacheFile = cacheFile,
101
+ _fileChunkThreshold = fileChunkThreshold;
97
102
98
103
final File _cacheFile;
99
104
final Logger _logger;
100
105
final FileStoreStrategy _strategy;
106
+ final int _fileChunkThreshold;
101
107
102
108
final HashMap <String , String > previousAssetKeys = HashMap <String , String >();
103
109
final HashMap <String , String > currentAssetKeys = HashMap <String , String >();
@@ -229,7 +235,18 @@ class FileStore {
229
235
dirty.add (file);
230
236
return ;
231
237
}
232
- final Digest digest = md5.convert (await file.readAsBytes ());
238
+ Digest digest;
239
+ final int fileBytes = file.lengthSync ();
240
+ // For files larger than a given threshold, chunk the conversion.
241
+ if (fileBytes > _fileChunkThreshold) {
242
+ final StreamController <Digest > digests = StreamController <Digest >();
243
+ final ByteConversionSink inputSink = md5.startChunkedConversion (digests);
244
+ await file.openRead ().forEach (inputSink.add);
245
+ inputSink.close ();
246
+ digest = await digests.stream.last;
247
+ } else {
248
+ digest = md5.convert (await file.readAsBytes ());
249
+ }
233
250
final String currentHash = digest.toString ();
234
251
if (currentHash != previousHash) {
235
252
dirty.add (file);
0 commit comments