Spaces:
Sleeping
Sleeping
Add UTF-8 encoding support for Windows in simulation_runner.py and run_parallel_simulation.py to resolve character encoding issues with third-party libraries.
Browse files
backend/app/services/simulation_runner.py
CHANGED
|
@@ -423,6 +423,12 @@ class SimulationRunner:
|
|
| 423 |
main_log_path = os.path.join(sim_dir, "simulation.log")
|
| 424 |
main_log_file = open(main_log_path, 'w', encoding='utf-8')
|
| 425 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 426 |
# 设置工作目录为模拟目录(数据库等文件会生成在此)
|
| 427 |
# 使用 start_new_session=True 创建新的进程组,确保可以通过 os.killpg 终止所有子进程
|
| 428 |
process = subprocess.Popen(
|
|
@@ -431,7 +437,9 @@ class SimulationRunner:
|
|
| 431 |
stdout=main_log_file,
|
| 432 |
stderr=subprocess.STDOUT, # stderr 也写入同一个文件
|
| 433 |
text=True,
|
|
|
|
| 434 |
bufsize=1,
|
|
|
|
| 435 |
start_new_session=True, # 创建新进程组,确保服务器关闭时能终止所有相关进程
|
| 436 |
)
|
| 437 |
|
|
|
|
| 423 |
main_log_path = os.path.join(sim_dir, "simulation.log")
|
| 424 |
main_log_file = open(main_log_path, 'w', encoding='utf-8')
|
| 425 |
|
| 426 |
+
# 设置子进程环境变量,确保 Windows 上使用 UTF-8 编码
|
| 427 |
+
# 这可以修复第三方库(如 OASIS)读取文件时未指定编码的问题
|
| 428 |
+
env = os.environ.copy()
|
| 429 |
+
env['PYTHONUTF8'] = '1' # Python 3.7+ 支持,让所有 open() 默认使用 UTF-8
|
| 430 |
+
env['PYTHONIOENCODING'] = 'utf-8' # 确保 stdout/stderr 使用 UTF-8
|
| 431 |
+
|
| 432 |
# 设置工作目录为模拟目录(数据库等文件会生成在此)
|
| 433 |
# 使用 start_new_session=True 创建新的进程组,确保可以通过 os.killpg 终止所有子进程
|
| 434 |
process = subprocess.Popen(
|
|
|
|
| 437 |
stdout=main_log_file,
|
| 438 |
stderr=subprocess.STDOUT, # stderr 也写入同一个文件
|
| 439 |
text=True,
|
| 440 |
+
encoding='utf-8', # 显式指定编码
|
| 441 |
bufsize=1,
|
| 442 |
+
env=env, # 传递带有 UTF-8 设置的环境变量
|
| 443 |
start_new_session=True, # 创建新进程组,确保服务器关闭时能终止所有相关进程
|
| 444 |
)
|
| 445 |
|
backend/scripts/run_parallel_simulation.py
CHANGED
|
@@ -25,16 +25,53 @@ OASIS 双平台并行模拟预设脚本
|
|
| 25 |
└── run_state.json # 运行状态(API 查询用)
|
| 26 |
"""
|
| 27 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
import argparse
|
| 29 |
import asyncio
|
| 30 |
import json
|
| 31 |
import logging
|
| 32 |
import multiprocessing
|
| 33 |
-
import os
|
| 34 |
import random
|
| 35 |
import signal
|
| 36 |
import sqlite3
|
| 37 |
-
import sys
|
| 38 |
import warnings
|
| 39 |
from datetime import datetime
|
| 40 |
from typing import Dict, Any, List, Optional, Tuple
|
|
|
|
| 25 |
└── run_state.json # 运行状态(API 查询用)
|
| 26 |
"""
|
| 27 |
|
| 28 |
+
# ============================================================
|
| 29 |
+
# 解决 Windows 编码问题:在所有 import 之前设置 UTF-8 编码
|
| 30 |
+
# 这是为了修复 OASIS 第三方库读取文件时未指定编码的问题
|
| 31 |
+
# ============================================================
|
| 32 |
+
import sys
|
| 33 |
+
import os
|
| 34 |
+
|
| 35 |
+
if sys.platform == 'win32':
|
| 36 |
+
# 设置 Python 默认 I/O 编码为 UTF-8
|
| 37 |
+
# 这会影响所有未指定编码的 open() 调用
|
| 38 |
+
os.environ.setdefault('PYTHONUTF8', '1')
|
| 39 |
+
os.environ.setdefault('PYTHONIOENCODING', 'utf-8')
|
| 40 |
+
|
| 41 |
+
# 重新配置标准输出流为 UTF-8(解决控制台中文乱码)
|
| 42 |
+
if hasattr(sys.stdout, 'reconfigure'):
|
| 43 |
+
sys.stdout.reconfigure(encoding='utf-8', errors='replace')
|
| 44 |
+
if hasattr(sys.stderr, 'reconfigure'):
|
| 45 |
+
sys.stderr.reconfigure(encoding='utf-8', errors='replace')
|
| 46 |
+
|
| 47 |
+
# 强制设置默认编码(影响 open() 函数的默认编码)
|
| 48 |
+
# 注意:这需要在 Python 启动时就设置,运行时设置可能不生效
|
| 49 |
+
# 所以我们还需要 monkey-patch 内置的 open 函数
|
| 50 |
+
import builtins
|
| 51 |
+
_original_open = builtins.open
|
| 52 |
+
|
| 53 |
+
def _utf8_open(file, mode='r', buffering=-1, encoding=None, errors=None,
|
| 54 |
+
newline=None, closefd=True, opener=None):
|
| 55 |
+
"""
|
| 56 |
+
包装 open() 函数,对于文本模式默认使用 UTF-8 编码
|
| 57 |
+
这可以修复第三方库(如 OASIS)读取文件时未指定编码的问题
|
| 58 |
+
"""
|
| 59 |
+
# 只对文本模式(非二进制)且未指定编码的情况设置默认编码
|
| 60 |
+
if encoding is None and 'b' not in mode:
|
| 61 |
+
encoding = 'utf-8'
|
| 62 |
+
return _original_open(file, mode, buffering, encoding, errors,
|
| 63 |
+
newline, closefd, opener)
|
| 64 |
+
|
| 65 |
+
builtins.open = _utf8_open
|
| 66 |
+
|
| 67 |
import argparse
|
| 68 |
import asyncio
|
| 69 |
import json
|
| 70 |
import logging
|
| 71 |
import multiprocessing
|
|
|
|
| 72 |
import random
|
| 73 |
import signal
|
| 74 |
import sqlite3
|
|
|
|
| 75 |
import warnings
|
| 76 |
from datetime import datetime
|
| 77 |
from typing import Dict, Any, List, Optional, Tuple
|