'''
此脚本适用于两个主机之间通过串口进行文件传输,传输速率取决与USB转UART的比特率。建议文件传输前先进行压缩。
'''
import math
import serial
import time
import os
class SerialPort:
def __init__(self, port, baud_rate=6000000, timeout=1,buffer=4096):
self.port = port
self.baud_rate = baud_rate
self.timeout = timeout
self.ser = None
self.buffer = buffer
def open(self):
try:
self.ser = serial.Serial(self.port, self.baud_rate, timeout=self.timeout)
if self.ser.is_open:
print(f"串口 {self.port} 已打开")
else:
raise serial.SerialException(f"无法打开串口 {self.port}")
except serial.SerialException as e:
print(f"串口错误: {e}")
def close(self):
if self.ser and self.ser.is_open:
self.ser.close()
print(f"串口 {self.port} 已关闭")
def read_file(self,filename):
while True:
file_size = os.path.getsize(filename)
chunk_number = math.ceil(file_size/self.buffer)
file_name = (filename.split("\\"))[-1]
self.ser.write(f"wenjianxinxi,{file_name},{chunk_number}".encode())
time.sleep(1)
with open(filename, 'rb') as file:
while chunk := file.read(self.buffer): # 每次读取n个字节
chunk_number = chunk_number-1
print(chunk_number)
self.ser.write(chunk)
while self.ser.read(6) != "r_ok_!".encode():
pass
time.sleep(2)
self.ser.write("wenjianchuanshujieshu".encode())
break
def write_file(self):
file = None
while True:
data = self.ser.read(self.buffer)
if "wenjianxinxi".encode() in data:
buf = data.split(",".encode())
filename = buf[1].decode()
filesize = buf[2].decode()
chunk_number = int(filesize)
file = open("copy_"+filename,'ab')
print(f"获取文件信息成功:{filename}_{filesize}")
elif "wenjianchuanshujieshu".encode() in data:
print("文件传输结束")
break
elif len(data) != 0:
chunk_number = chunk_number-1
print(chunk_number)
file.write(data)
self.ser.write("r_ok_!".encode())
def __del__(self):
# 确保在对象被销毁时关闭串口
self.close()
# 使用示例
if __name__ == "__main__":
serial_port = SerialPort('COM19',baud_rate=6000000, buffer=4096) # 根据实际情况修改串口号,波特率,和buffer
serial_port.open()
#接收文件
serial_port.write_file()
#发送文件
# serial_port.read_file(r"D:\Users\logan.lei\Downloads\晶体管电路设计 (铃木雅臣).pdf")
'''
baud_rate 需要看自己的USB转串口模块都支持那些波特率;buffer 是自己串口模块的收/发缓冲区大小,一般发送缓冲区和接受缓冲区大小不一样,需要选择两者较小者。
'''