@@ -181,7 +181,8 @@ def cluster_from_attribute_non_resident(attribute, cluster_num = 0, size_max = (
181181
182182 data = ''
183183 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 )
185186 end
186187 attribut << data
187188 end
@@ -196,8 +197,11 @@ def cluster_from_attribute_non_resident(attribute, cluster_num = 0, size_max = (
196197 #
197198 # return the attribute list from the MFT record
198199 # 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.
199203 #
200- def mft_record_attribute ( mft_record )
204+ def mft_record_attribute ( mft_record , lazy = true )
201205 attribute_list_offset = mft_record [ 20 , 2 ] . unpack ( 'C' ) [ 0 ]
202206 curs = attribute_list_offset
203207 attribute_identifier = mft_record [ curs , 4 ] . unpack ( 'V' ) [ 0 ]
@@ -213,10 +217,11 @@ def mft_record_attribute(mft_record)
213217 res [ attribute_identifier ] = mft_record [ curs + content_offset , content_size ]
214218 else
215219 # 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 )
219222 res [ attribute_identifier ] = cluster_from_attribute_non_resident ( mft_record [ curs , attribute_size ] )
223+ else
224+ res [ attribute_identifier ] = mft_record [ curs , attribute_size ]
220225 end
221226 end
222227 if attribute_identifier == DATA_ATTRIBUTE_ID
0 commit comments