import importlib.resources
import os
import logging
from typing import Dict, Any, Optional
logger = logging.getLogger(__name__)
class FileUtils:
"""
文件操作工具类
提供文件路径验证、文件存在性检查、不同格式文件的读取方法和错误处理机制
"""
@staticmethod
def is_valid_path(path: str) -> bool:
"""
验证文件路径是否有效
:param path: 文件路径
:return: 是否有效
"""
if not path:
return False
invalid_chars = '<>"|?*'
for char in invalid_chars:
if char in path:
return False
return True
@staticmethod
def exists(path: str) -> bool:
"""
检查文件是否存在
:param path: 文件路径
:return: 是否存在
"""
return os.path.exists(path) and os.path.isfile(path)
@staticmethod
def read_properties_file(file_path: str) -> Dict[str, str]:
"""
读取properties格式文件
:param file_path: 文件路径
:return: 键值对字典
"""
props = {}
if not FileUtils.exists(file_path):
return props
try:
with open(file_path, "r", encoding="utf-8") as f:
for line in f:
line = line.strip()
if not line or line.startswith("#"):
continue
if "=" in line:
key, value = line.split("=", maxsplit=1)
props[key] = value
except UnicodeDecodeError:
try:
with open(file_path, "r", encoding="gbk") as f:
for line in f:
line = line.strip()
if not line or line.startswith("#"):
continue
if "=" in line:
key, value = line.split("=", maxsplit=1)
props[key] = value
except Exception as e:
logger.error(f"Failed to read properties file {file_path}: {e}")
except Exception as e:
logger.error(f"Failed to read properties file {file_path}: {e}")
return props
@staticmethod
def read_yaml_file(file_path: str) -> Optional[Dict[str, Any]]:
"""
读取YAML格式文件
:param file_path: 文件路径
:return: YAML数据字典,失败返回None
"""
if not FileUtils.exists(file_path):
logger.warning(f"YAML file not found: {file_path}")
return None
try:
import yaml
with open(file_path, "r", encoding="utf-8") as f:
return yaml.safe_load(f)
except ImportError:
logger.error("PyYAML library is not installed")
return None
except Exception as e:
logger.error(f"Failed to read YAML file {file_path}: {e}")
return None
@staticmethod
def read_file_as_string(file_path: str) -> Optional[str]:
"""
读取文件内容为字符串
:param file_path: 文件路径
:return: 文件内容字符串,失败返回None
"""
if not FileUtils.exists(file_path):
logger.error(f"file is not exist: {file_path}")
return None
try:
with open(file_path, "r", encoding="utf-8") as file:
file_content = file.read()
return file_content
except PermissionError as e:
logger.error(f"no permission to read {file_path}")
return None
except Exception as e:
logger.error(f"read error {file_path} err: {e}")
return None
@staticmethod
def get_package_data(path: str) -> Optional[str]:
"""
获取项目内资源文件数据
:param path: 资源路径
:return:
"""
return importlib.resources.files("olc").joinpath(path).read_text(encoding="utf-8")