Open landv opened 4 weeks ago
import os import zlib from io import BytesIO from PyQt5 import QtWidgets, QtCore from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog, QMessageBox class FileToolGUI(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("文件压缩/解压缩工具") self.initUI() def initUI(self): self.action = 'decompress' # 默认操作为解压缩 self.resize(308, 266) central_widget = QtWidgets.QWidget() self.setCentralWidget(central_widget) layout = QtWidgets.QVBoxLayout() # 操作选择部分 operation_label = QtWidgets.QLabel("选择操作:") layout.addWidget(operation_label) self.decompress_radio = QtWidgets.QRadioButton("解压缩") self.decompress_radio.setChecked(True) self.compress_radio = QtWidgets.QRadioButton("压缩") radio_layout = QtWidgets.QHBoxLayout() radio_layout.addWidget(self.decompress_radio) radio_layout.addWidget(self.compress_radio) layout.addLayout(radio_layout) self.decompress_radio.toggled.connect(lambda: self.on_radio_toggled('decompress')) self.compress_radio.toggled.connect(lambda: self.on_radio_toggled('compress')) # 输入路径选择部分 input_label = QtWidgets.QLabel("输入路径:") layout.addWidget(input_label) self.input_entry = QtWidgets.QLineEdit() layout.addWidget(self.input_entry) select_input_button = QtWidgets.QPushButton("选择输入路径") select_input_button.clicked.connect(self.select_input) layout.addWidget(select_input_button) # 输出路径选择部分 output_label = QtWidgets.QLabel("输出路径:") layout.addWidget(output_label) self.output_entry = QtWidgets.QLineEdit() layout.addWidget(self.output_entry) select_output_button = QtWidgets.QPushButton("选择输出路径") select_output_button.clicked.connect(self.select_output) layout.addWidget(select_output_button) # 开始按钮 start_button = QtWidgets.QPushButton("开始") start_button.clicked.connect(self.process_files) layout.addWidget(start_button) central_widget.setLayout(layout) def on_radio_toggled(self, action): self.action = action def select_input(self): if self.action == 'decompress': input_path, _ = QFileDialog.getOpenFileName(self, "选择文件", "", "All Files (*);;Binary Files (*.bin)") else: input_path = QFileDialog.getExistingDirectory(self, "选择文件夹") if input_path: self.input_entry.setText(input_path) def select_output(self): if self.action == 'decompress': output_path = QFileDialog.getExistingDirectory(self, "选择文件夹") else: output_path, _ = QFileDialog.getSaveFileName(self, "保存文件", "", "Library Files (*.lib)") if output_path: self.output_entry.setText(output_path) def process_files(self): input_path = self.input_entry.text() output_path = self.output_entry.text() if not input_path or not output_path: QMessageBox.critical(self, "错误", "请指定输入和输出路径") return if self.action == 'decompress': parsed_data = parse_binary_file(input_path) display_parsed_data(parsed_data, output_path) QMessageBox.information(self, "完成", "文件解压缩完成") elif self.action == 'compress': compress_files(input_path, output_path) QMessageBox.information(self, "完成", "文件压缩完成") def parse_binary_file(file_path): map = {} with open(file_path, 'rb') as file: compressed_data = file.read() decompressed_data = zlib.decompress(compressed_data) byte_stream = BytesIO(decompressed_data) while byte_stream.tell() < len(decompressed_data): name_length = int.from_bytes(byte_stream.read(2), 'big') name = byte_stream.read(name_length).decode('utf-8') file_length = int.from_bytes(byte_stream.read(4), 'big') file_content = byte_stream.read(file_length) map[name] = file_content return map def display_parsed_data(parsed_data, output_folder): for name, content in parsed_data.items(): try: output_file_path = os.path.join(output_folder, name) os.makedirs(os.path.dirname(output_file_path), exist_ok=True) with open(output_file_path, 'wb') as outfile: outfile.write(content) except UnicodeDecodeError: print(f'File Name: {name}') print('Content: [无法解码为UTF-8]') def compress_files(input_folder, output_file_path): byte_stream = BytesIO() for root, dirs, files in os.walk(input_folder): for file_name in files: if file_name.endswith('.xml'): file_path = os.path.join(root, file_name) with open(file_path, 'rb') as file: file_content = file.read() name_bytes = file_name.encode('utf-8') name_length = len(name_bytes) byte_stream.write(name_length.to_bytes(2, 'big')) byte_stream.write(name_bytes) file_length = len(file_content) byte_stream.write(file_length.to_bytes(4, 'big')) byte_stream.write(file_content) uncompressed_data = byte_stream.getvalue() compressed_data = zlib.compress(uncompressed_data) with open(output_file_path, 'wb') as output_file: output_file.write(compressed_data) if __name__ == "__main__": app = QApplication([]) window = FileToolGUI() window.show() app.exec_()
# 创建虚拟环境(可选步骤,如果你还没有虚拟环境) python -m venv venv # 激活虚拟环境 # Windows venv\Scripts\activate pip install PyQt5 pyinstaller python.exe -m pip install --upgrade pip pyinstaller --onefile --windowed --hidden-import PyQt5 flashXmlLibToolsQTGui.py pyinstaller flashXmlLibToolsQTGui.spec #记得目录不能有中文 # 混淆加密 pyarmor g pyarmor cfg pack:pyi_options = " -w --hidden-import PyQt5" pyarmor cfg pyarmor gen --pack onefile flashXmlLibToolsQTGui.py # https://pyarmor.readthedocs.io/en/latest/topic/repack.html#packing-scripts-automatically
flash xmlLib zlib 压缩和解压缩