33import io
44import sys
55import traceback
6+ from typing import Dict , Set , List , Optional , Any
67from .constants import *
78from .mft_record import MftRecord
89
910class MftAnalyzer :
1011
11- def __init__ (self , mft_file , output_file , debug = False , compute_hashes = False ) :
12+ def __init__ (self , mft_file : str , output_file : str , debug : bool = False , compute_hashes : bool = False , export_format : str = "csv" ) -> None :
1213 self .mft_file = mft_file
1314 self .output_file = output_file
1415 self .debug = debug
1516 self .compute_hashes = compute_hashes
16- self .mft_records = {}
17+ self .export_format = export_format
18+ self .mft_records = []
1719 self .interrupt_flag = asyncio .Event ()
1820 self .csv_writer = None
1921 self .csvfile = None
@@ -32,30 +34,19 @@ def __init__(self, mft_file, output_file, debug=False, compute_hashes=False):
3234 })
3335
3436
35- async def analyze (self ):
37+ async def analyze (self ) -> None :
3638 try :
37- self .csvfile = io .open (self .output_file , 'w' , newline = '' , encoding = 'utf-8' )
38- self .csv_writer = csv .writer (self .csvfile )
39- header = CSV_HEADER .copy ()
40- if self .compute_hashes :
41- header .extend (['MD5' , 'SHA256' , 'SHA512' , 'CRC32' ])
42- self .csv_writer .writerow (header )
43-
44- self .handle_interrupt ()
4539 await self .process_mft ()
46-
40+ await self . write_output ()
4741 except Exception as e :
4842 print (f"An unexpected error occurred: { e } " )
4943 if self .debug :
5044 traceback .print_exc ()
5145 finally :
52- await self .write_remaining_records ()
5346 self .print_statistics ()
54- if self .csvfile :
55- self .csvfile .close ()
56- print (f"Analysis complete. Results written to { self .output_file } " )
5747
58- async def process_mft (self ):
48+
49+ async def process_mft (self ) -> None :
5950 try :
6051 with open (self .mft_file , 'rb' ) as f :
6152 while not self .interrupt_flag .is_set ():
@@ -100,7 +91,7 @@ async def process_mft(self):
10091 if self .debug :
10192 traceback .print_exc ()
10293
103- def handle_interrupt (self ):
94+ def handle_interrupt (self ) -> None :
10495 if sys .platform == "win32" :
10596 # Windows-specific interrupt handling
10697 import win32api
@@ -120,7 +111,7 @@ def unix_handler():
120111 getattr (signal , signame ),
121112 unix_handler )
122113
123- async def write_csv_block (self ):
114+ async def write_csv_block (self ) -> None :
124115 try :
125116 for record in self .mft_records .values ():
126117 filepath = self .build_filepath (record )
@@ -143,11 +134,11 @@ async def write_csv_block(self):
143134 traceback .print_exc ()
144135
145136
146- async def write_remaining_records (self ):
137+ async def write_remaining_records (self ) -> None :
147138 await self .write_csv_block ()
148139 self .mft_records .clear ()
149140
150- def build_filepath (self , record ) :
141+ def build_filepath (self , record : MftRecord ) -> str :
151142 path_parts = []
152143 current_record = record
153144 max_depth = 255
@@ -179,7 +170,7 @@ def build_filepath(self, record):
179170
180171 return '\\ ' .join (path_parts )
181172
182- def print_statistics (self ):
173+ def print_statistics (self ) -> None :
183174 print ("\n MFT Analysis Statistics:" )
184175 print (f"Total records processed: { self .stats ['total_records' ]} " )
185176 print (f"Active records: { self .stats ['active_records' ]} " )
@@ -191,3 +182,15 @@ def print_statistics(self):
191182 print (f"Unique SHA512 hashes: { len (self .stats ['unique_sha512' ])} " )
192183 print (f"Unique CRC32 hashes: { len (self .stats ['unique_crc32' ])} " )
193184
185+
186+ async def write_output (self ) -> None :
187+ if self .export_format == "csv" :
188+ await FileWriters .write_csv (self .mft_records , self .output_file )
189+ elif self .export_format == "json" :
190+ await FileWriters .write_json (self .mft_records , self .output_file )
191+ elif self .export_format == "xml" :
192+ await FileWriters .write_xml (self .mft_records , self .output_file )
193+ elif self .export_format == "excel" :
194+ await FileWriters .write_excel (self .mft_records , self .output_file )
195+ else :
196+ print (f"Unsupported export format: { self .export_format } " )
0 commit comments