如何用Python在GCode文件中每隔指定层数插入喷嘴清洁代码?
解决大GCode文件每隔X层插入喷嘴清洁代码的问题
原脚本的核心问题
- 明明用了
mmap却又调用file.readlines()把整个文件加载到内存,完全没发挥mmap处理大文件的优势,反而浪费内存 - 遍历列表时直接
contents.insert(index, ...),会导致列表长度动态变化,后续循环重复处理元素,逻辑彻底混乱 - 没有实现「每隔X层」的判断逻辑,当前逻辑是每层都插,不符合需求
- 字符串转换和写入时重复添加换行符,导致输出文件格式错乱
重写后的脚本(高效处理大文件)
下面的脚本采用逐行读取写入的方式,无需把78MB的文件全加载到内存,同时完美实现每隔X层插入清洁代码的逻辑:
#!/usr/bin/env python3 # 可配置参数 X = 5 # 每隔X层执行一次喷嘴清洁 CLEAN_CODE = """;Clean Nozzle G0 X30 Y-47 F10000 G0 X70 Y-47 G0 X30 Y-47 """ INPUT_PATH = r'C:\Users\Adam.Widdowson\Desktop\gcode\TestSmall.gcode' OUTPUT_PATH = r'C:\Users\Adam.Widdowson\Desktop\gcode\New.gcode' def main(): layer_count = 0 # 统计层数,遇到层标记行就递增 with open(INPUT_PATH, 'r', encoding='utf-8') as infile, \ open(OUTPUT_PATH, 'w', encoding='utf-8') as outfile: for line in infile: # 先写入当前行到输出文件 outfile.write(line) # 判断当前行是否为层标记行(忽略大小写和前后空格) if 'layer' in line.strip().lower(): layer_count += 1 # 按需调整判断逻辑: # - 若要第X、2X、3X...层执行,用 layer_count % X == 0 # - 若要从第1层开始每隔X层(1、6、11...),用 (layer_count - 1) % X == 0 if layer_count % X == 0: # 插入清洁代码,末尾加换行保证格式统一 outfile.write(CLEAN_CODE + '\n') if __name__ == '__main__': main() print('处理完成')
关键逻辑说明
- 逐行处理:避免一次性加载大文件到内存,78MB级别的文件完全能轻松处理
- 层数判断:通过
layer_count统计层标记行数,用取模运算精准控制清洁间隔 - 插入时机:先写入原层标记行,再插入清洁代码,确保代码在目标行的下方
- 灵活配置:所有可变参数都放在脚本开头,修改起来不用动核心逻辑
可选:用mmap处理大文件(适合随机访问场景)
如果确实需要用mmap(比如要做复杂的随机定位操作),可以参考以下实现,但对于当前需求,逐行处理更简单高效:
#!/usr/bin/env python3 import mmap X = 5 CLEAN_CODE = """;Clean Nozzle G0 X30 Y-47 F10000 G0 X70 Y-47 G0 X30 Y-47 """ INPUT_PATH = r'C:\Users\Adam.Widdowson\Desktop\gcode\TestSmall.gcode' OUTPUT_PATH = r'C:\Users\Adam.Widdowson\Desktop\gcode\New.gcode' def main(): layer_count = 0 with open(INPUT_PATH, 'rb') as infile, \ mmap.mmap(infile.fileno(), 0, access=mmap.ACCESS_READ) as mm, \ open(OUTPUT_PATH, 'wb') as outfile: # 按行分割mmap内容(保留原换行符) lines = mm.read().splitlines(keepends=True) for line in lines: outfile.write(line) # 转字符串判断是否为层标记行 line_str = line.decode('utf-8') if 'layer' in line_str.strip().lower(): layer_count +=1 if layer_count % X ==0: # 转字节写入清洁代码 outfile.write(CLEAN_CODE.encode('utf-8') + b'\n') print('处理完成') if __name__ == '__main__': main()
注意事项
- 层标记行判断用了
strip().lower(),避免因大小写、前后空格导致漏判 - 清洁代码末尾的换行可根据原GCode格式调整,保证输出文件格式正确
- 测试时先用小文件验证逻辑,再处理大文件
内容的提问来源于stack exchange,提问作者AdWidd
相关产品推荐
相关产品推荐

