@@ -181,7 +181,8 @@ def cluster_from_attribute_non_resident(attribute, cluster_num = 0, size_max = (
181
181
182
182
data = ''
183
183
while data . length < size_wanted
184
- data << @file_handler . read ( size_wanted - data . length )
184
+ # Use a 4Mb block size to avoid target memory consumption
185
+ data << @file_handler . read ( [ size_wanted - data . length , 2 **22 ] . min )
185
186
end
186
187
attribut << data
187
188
end
@@ -196,8 +197,11 @@ def cluster_from_attribute_non_resident(attribute, cluster_num = 0, size_max = (
196
197
#
197
198
# return the attribute list from the MFT record
198
199
# deal with resident and non resident attributes (but not $DATA due to performance issue)
200
+ # if lazy = True, this function only gather essential non resident attributes
201
+ # (INDEX_ALLOCATION). Non resident attributes can still be gathered later with
202
+ # cluster_from_attribute_non_resident function.
199
203
#
200
- def mft_record_attribute ( mft_record )
204
+ def mft_record_attribute ( mft_record , lazy = true )
201
205
attribute_list_offset = mft_record [ 20 , 2 ] . unpack ( 'C' ) [ 0 ]
202
206
curs = attribute_list_offset
203
207
attribute_identifier = mft_record [ curs , 4 ] . unpack ( 'V' ) [ 0 ]
@@ -213,10 +217,11 @@ def mft_record_attribute(mft_record)
213
217
res [ attribute_identifier ] = mft_record [ curs + content_offset , content_size ]
214
218
else
215
219
# non resident
216
- if attribute_identifier == DATA_ATTRIBUTE_ID
217
- res [ attribute_identifier ] = mft_record [ curs , attribute_size ]
218
- else
220
+ if attribute_identifier == INDEX_ALLOCATION_ID or
221
+ ( !lazy and attribute_identifier != DATA_ATTRIBUTE_ID )
219
222
res [ attribute_identifier ] = cluster_from_attribute_non_resident ( mft_record [ curs , attribute_size ] )
223
+ else
224
+ res [ attribute_identifier ] = mft_record [ curs , attribute_size ]
220
225
end
221
226
end
222
227
if attribute_identifier == DATA_ATTRIBUTE_ID
0 commit comments