当前位置:首页>python>Python全栈修炼之路 | 第8篇:文件操作与异常处理

Python全栈修炼之路 | 第8篇:文件操作与异常处理

  • 2026-06-29 19:40:43
Python全栈修炼之路 | 第8篇:文件操作与异常处理

前言

文件操作是程序与外部世界交互的基础,而异常处理则是保证程序健壮性的关键机制。本文将深入讲解Python中的文件读写、路径操作和异常处理,从基础用法到底层原理,帮助你编写出既功能完善又稳定可靠的代码。


一、文件读写基础

1.1 打开文件

Python使用内置的open()函数打开文件:

# 基础语法file = open('data.txt', 'r', encoding='utf-8')content = file.read()file.close()# 模式说明# 'r'  - 读取(默认)# 'w'  - 写入(覆盖)# 'a'  - 追加# 'x'  - 独占创建(文件已存在则失败)# 'b'  - 二进制模式# '+'  - 读写模式# 常用组合# 'rb' - 读取二进制文件# 'w+' - 读写(覆盖)# 'a+' - 读写(追加)

1.2 读取文件

# 方法1: 一次性读取全部内容with open('data.txt''r', encoding='utf-8'as f:    content = f.read()    print(content)# 方法2: 按行读取(适合大文件)with open('data.txt''r', encoding='utf-8'as f:    for line in f:        print(line.strip())  # strip()去除换行符# 方法3: 读取所有行到列表with open('data.txt''r', encoding='utf-8'as f:    lines = f.readlines()# 方法4: 读取指定字节数(二进制文件)with open('image.png''rb'as f:    chunk = f.read(1024)  # 读取1024字节

1.3 写入文件

# 写入文本data = ["第一行""第二行""第三行"]with open('output.txt''w', encoding='utf-8'as f:    for line in data:        f.write(line + '\n')# 使用writelines(不会自动添加换行)with open('output.txt''w', encoding='utf-8'as f:    f.writelines(line + '\n' for line in data)# 追加模式with open('log.txt''a', encoding='utf-8'as f:    f.write("新的日志条目\n")

二、with上下文管理器

2.1 为什么需要with语句

传统文件操作的问题:

# ❌ 容易忘记关闭文件f = open('data.txt''r')data = f.read()# 如果这里发生异常,文件永远不会关闭!f.close()# ❌ 即使使用try-finally也很冗长f = open('data.txt''r')try:    data = f.read()finally:    f.close()

2.2 with语句的优势

# ✅ 简洁且安全withopen('data.txt''r', encoding='utf-8'as f:    data = f.read()# 文件自动关闭,即使在with块中发生异常

2.3 上下文管理协议

with语句的背后是上下文管理协议,需要实现两个特殊方法:

class ManagedFile:    """自定义上下文管理器"""    def __init__(self, filename, mode='r'):        self.filename = filename        self.mode = mode        self.file = None    def __enter__(self):        """进入上下文时调用"""        print(f"打开文件: {self.filename}")        self.file = open(self.filename, self.mode)        return self.file    def __exit__(self, exc_type, exc_val, exc_tb):        """退出上下文时调用"""        if self.file:            self.file.close()            print(f"关闭文件: {self.filename}")        # 返回True表示异常已处理,不再传播        # 返回False或不返回,异常会继续传播        if exc_type:            print(f"发生异常: {exc_val}")        return False# 使用自定义上下文管理器with ManagedFile('test.txt''w'as f:    f.write("Hello, World!")

2.4 contextlib简化实现

from contextlib import contextmanager@contextmanagerdef managed_file(filename, mode='r'):    """使用装饰器简化上下文管理器"""    f = open(filename, mode)    try:        yield f    finally:        f.close()# 使用with managed_file('test.txt''w'as f:    f.write("Hello!")# 更实用的例子:计时上下文管理器import timefrom contextlib import contextmanager@contextmanagerdef timer(name="操作"):    start = time.time()    yield    elapsed = time.time() - start    print(f"{name} 耗时: {elapsed:.4f}秒")with timer("数据处理"):    time.sleep(1)

三、路径操作:pathlib vs os.path

3.1 pathlib模块(推荐)

Python 3.4+引入的pathlib提供了面向对象的路径操作:

from pathlib import Path# 创建路径对象p = Path('/home/user/documents')# 路径拼接(使用/运算符)file_path = p / 'report' / '2024' / 'data.txt'print(file_path)# /home/user/documents/report/2024/data.txt# 常用属性和方法print(file_path.name)       # data.txt(文件名)print(file_path.stem)       # data(不含扩展名)print(file_path.suffix)     # .txt(扩展名)print(file_path.parent)     # /home/user/documents/report/2024(父目录)print(file_path.parts)      # ('/', 'home', 'user', ...)# 路径检查print(file_path.exists())       # 是否存在print(file_path.is_file())      # 是否是文件print(file_path.is_dir())       # 是否是目录print(file_path.is_absolute())  # 是否是绝对路径

3.2 文件系统操作

from pathlib import Pathp = Path('example.txt')# 文件操作p.write_text('Hello, World!', encoding='utf-8')  # 写入文本content = p.read_text(encoding='utf-8')           # 读取文本p.write_bytes(b'Binary data')                     # 写入二进制bytes_content = p.read_bytes()                    # 读取二进制# 目录操作dir_path = Path('my_folder')dir_path.mkdir(parents=True, exist_ok=True)  # 创建目录(包括父目录)# 遍历目录for item in dir_path.iterdir():    print(item)# 递归遍历for py_file in dir_path.rglob('*.py'):    print(py_file)# 文件重命名和删除p.rename('new_name.txt')p.replace(Path('backup') / 'new_name.txt')  # 移动并覆盖p.unlink()  # 删除文件dir_path.rmdir()  # 删除空目录

3.3 pathlib vs os.path 对比

操作
pathlib (推荐)
os.path (旧式)
路径拼接
p / 'file.txt'os.path.join(p, 'file.txt')
获取文件名
p.nameos.path.basename(p)
获取目录
p.parentos.path.dirname(p)
获取扩展名
p.suffixos.path.splitext(p)[1]
绝对路径
p.resolve()os.path.abspath(p)
是否存在
p.exists()os.path.exists(p)
读取文件
p.read_text()open(p).read()
# pathlib的优势示例from pathlib import Pathimport os# 查找所有Python文件并计算总行数total_lines = 0for py_file in Path('.').rglob('*.py'):    total_lines += len(py_file.read_text(encoding='utf-8').splitlines())print(f"Python文件总行数: {total_lines}")# 使用os.path的等效代码(更冗长)total_lines = 0for root, dirs, files in os.walk('.'):    for file in files:        if file.endswith('.py'):            filepath = os.path.join(root, file)            with open(filepath, 'r', encoding='utf-8'as f:                total_lines += len(f.readlines())

四、异常处理机制

4.1 try/except/else/finally 结构

def divide(a, b):    try:        # 可能引发异常的代码        result = a / b    except ZeroDivisionError:        # 处理特定异常        print("错误:除数不能为零")        return None    except TypeError as e:        # 捕获异常对象        print(f"类型错误: {e}")        return None    except Exception as e:        # 捕获所有其他异常(谨慎使用)        print(f"未知错误: {e}")        return None    else:        # 没有异常时执行        print("计算成功")        return result    finally:        # 无论是否发生异常都执行        print("操作完成")# 测试print(divide(102))   # 正常情况print(divide(100))   # ZeroDivisionErrorprint(divide(10'a')) # TypeError

4.2 异常捕获的最佳实践

# ✅ 捕获具体的异常try:    value = int(user_input)except ValueError:    print("请输入有效的数字")# ❌ 不要捕获所有异常(会隐藏bug)try:    value = int(user_input)except:  # 捕获包括KeyboardInterrupt在内的所有异常    pass# ✅ 获取异常详情try:    risky_operation()except ValueError as e:    print(f"错误信息: {e}")    import traceback    traceback.print_exc()  # 打印完整堆栈# ✅ 多个异常一起捕获try:    process_data()except (ValueError, TypeError) as e:    print(f"数据错误: {e}")

4.3 自定义异常

class ValidationError(Exception):    """数据验证错误"""    passclass NotFoundError(Exception):    """资源未找到"""    def __init__(self, resource, resource_id):        self.resource = resource        self.resource_id = resource_id        super().__init__(f"{resource} '{resource_id}' 未找到")# 使用自定义异常def get_user(user_id):    user = database.find_user(user_id)    if user is None:        raise NotFoundError("用户", user_id)    return userdef validate_age(age):    if not isinstance(age, intor age < 0 or age > 150:        raise ValidationError("年龄必须在0-150之间")# 捕获自定义异常try:    user = get_user(123)    validate_age(user.age)except NotFoundError as e:    print(e)except ValidationError as e:    print(f"验证失败: {e}")

4.4 异常链和raise from

def read_config(filename):    try:        with open(filename, 'r'as f:            return json.load(f)    except FileNotFoundError as e:        # 保留原始异常信息,添加上下文        raise ConfigError(f"配置文件不存在: {filename}"from e    except json.JSONDecodeError as e:        raise ConfigError(f"配置文件格式错误: {filename}"from e# 查看异常链try:    config = read_config('app.json')except ConfigError as e:    print(f"当前异常: {e}")    print(f"原始异常: {e.__cause__}")

五、底层原理

5.1 文件描述符

操作系统通过文件描述符(File Descriptor)管理打开的文件:

# 获取文件描述符f = open('test.txt''r')print(f.fileno())  # 输出文件描述符(如3)# 文件描述符是有限的系统资源import osprint(f"当前进程打开的文件数: {len(os.listdir(f'/proc/{os.getpid()}/fd'))}")

为什么必须关闭文件?

  1. 释放文件描述符(系统资源有限)
  2. 确保缓冲区数据写入磁盘
  3. 允许其他进程访问文件

5.2 异常继承体系

Python异常类的层次结构:

BaseException ├── SystemExit              # sys.exit()引发 ├── KeyboardInterrupt       # Ctrl+C ├── GeneratorExit           # 生成器关闭 └── Exception               # 常规异常的基类      ├── ArithmeticError      │    └── ZeroDivisionError      ├── LookupError      │    ├── IndexError      │    └── KeyError      ├── TypeError      ├── ValueError      ├── RuntimeError      │    └── RecursionError      └── OSError           ├── FileNotFoundError           ├── PermissionError           └── TimeoutError
# 捕获多个相关异常try:    operation()except OSError as e:    # 捕获所有操作系统相关错误    print(f"系统错误: {e}")

5.3 上下文管理器的底层实现

# with语句的等价展开with EXPR as VAR:    BLOCK# 等价于mgr = (EXPR)exit = type(mgr).__exit__value = type(mgr).__enter__(mgr)exc = Truetry:    VAR = value    BLOCKexcept:    exc = False    if not exit(mgr, *sys.exc_info()):        raisefinally:    if exc:        exit(mgr, NoneNoneNone)

六、实战项目

6.1 日志记录系统

import jsonfrom datetime import datetimefrom pathlib import Pathfrom enum import Enumclass LogLevel(Enum):    DEBUG = "DEBUG"    INFO = "INFO"    WARNING = "WARNING"    ERROR = "ERROR"    CRITICAL = "CRITICAL"class Logger:    """简单的文件日志系统"""    def __init__(self, log_file='app.log', level=LogLevel.INFO):        self.log_file = Path(log_file)        self.level = level        self.levels = list(LogLevel)        # 确保日志目录存在        self.log_file.parent.mkdir(parents=True, exist_ok=True)    def _should_log(self, level):        """检查是否应该记录该级别的日志"""        return self.levels.index(level) >= self.levels.index(self.level)    def _write_log(self, level, message, **kwargs):        """写入日志"""        if not self._should_log(level):            return        entry = {            'timestamp': datetime.now().isoformat(),            'level': level.value,            'message': message        }        entry.update(kwargs)        with open(self.log_file, 'a', encoding='utf-8'as f:            f.write(json.dumps(entry, ensure_ascii=False) + '\n')    def debug(self, message, **kwargs):        self._write_log(LogLevel.DEBUG, message, **kwargs)    def info(self, message, **kwargs):        self._write_log(LogLevel.INFO, message, **kwargs)    def warning(self, message, **kwargs):        self._write_log(LogLevel.WARNING, message, **kwargs)    def error(self, message, **kwargs):        self._write_log(LogLevel.ERROR, message, **kwargs)    def critical(self, message, **kwargs):        self._write_log(LogLevel.CRITICAL, message, **kwargs)    def read_logs(self, level=None, limit=None):        """读取日志"""        if not self.log_file.exists():            return []        logs = []        with open(self.log_file, 'r', encoding='utf-8'as f:            for line in f:                entry = json.loads(line.strip())                if level is None or entry['level'] == level.value:                    logs.append(entry)        if limit:            logs = logs[-limit:]        return logs    def clear(self):        """清空日志"""        if self.log_file.exists():            self.log_file.unlink()# 使用示例logger = Logger('logs/myapp.log', LogLevel.DEBUG)logger.info("应用启动", version="1.0.0")logger.warning("内存使用率较高", usage="85%")logger.error("数据库连接失败", retry=3)print("\n最近的日志:")for log in logger.read_logs(limit=5):    print(f"[{log['level']}{log['timestamp']}{log['message']}")

6.2 配置文件读写

import jsonimport configparserfrom pathlib import Pathclass ConfigManager:    """支持多种格式的配置管理器"""    def __init__(self, config_path):        self.config_path = Path(config_path)        self.config = {}        self._load()    def _load(self):        """根据文件扩展名自动选择解析器"""        if not self.config_path.exists():            self.config = {}            return        suffix = self.config_path.suffix.lower()        try:            if suffix == '.json':                with open(self.config_path, 'r', encoding='utf-8'as f:                    self.config = json.load(f)            elif suffix in ('.ini''.cfg'):                parser = configparser.ConfigParser()                parser.read(self.config_path, encoding='utf-8')                self.config = {s: dict(parser[s]) for s in parser.sections()}            elif suffix in ('.yaml''.yml'):                import yaml                with open(self.config_path, 'r', encoding='utf-8'as f:                    self.config = yaml.safe_load(f)            else:                raise ValueError(f"不支持的配置文件格式: {suffix}")        except json.JSONDecodeError as e:            raise ConfigError(f"JSON解析错误: {e}"from e        except Exception as e:            raise ConfigError(f"加载配置失败: {e}"from e    def get(self, key, default=None):        """获取配置值(支持点号分隔的键)"""        keys = key.split('.')        value = self.config        for k in keys:            if isinstance(value, dictand k in value:                value = value[k]            else:                return default        return value    def set(self, key, value):        """设置配置值"""        keys = key.split('.')        config = self.config        for k in keys[:-1]:            if k not in config:                config[k] = {}            config = config[k]        config[keys[-1]] = value    def save(self):        """保存配置到文件"""        self.config_path.parent.mkdir(parents=True, exist_ok=True)        suffix = self.config_path.suffix.lower()        with open(self.config_path, 'w', encoding='utf-8'as f:            if suffix == '.json':                json.dump(self.config, f, indent=2, ensure_ascii=False)            elif suffix in ('.ini''.cfg'):                parser = configparser.ConfigParser()                for section, values in self.config.items():                    parser[section] = values                parser.write(f)    def __getitem__(self, key):        return self.config[key]    def __setitem__(self, key, value):        self.config[key] = value# 使用示例config = ConfigManager('app.json')config.set('database.host''localhost')config.set('database.port'3306)config.set('app.debug'True)config.save()print(f"数据库主机: {config.get('database.host')}")print(f"调试模式: {config.get('app.debug'False)}")

6.3 目录遍历工具

from pathlib import Pathfrom collections import defaultdictimport hashlibclass DirectoryAnalyzer:    """目录分析工具"""    def __init__(self, root_path):        self.root = Path(root_path)        if not self.root.exists():            raise FileNotFoundError(f"目录不存在: {root_path}")    def get_statistics(self):        """获取目录统计信息"""        stats = {            'total_files'0,            'total_dirs'0,            'total_size'0,            'extensions': defaultdict(int)        }        for item in self.root.rglob('*'):            if item.is_file():                stats['total_files'] += 1                stats['total_size'] += item.stat().st_size                stats['extensions'][item.suffix.lower()] += 1            elif item.is_dir():                stats['total_dirs'] += 1        return stats    def find_duplicates(self):        """查找重复文件(基于文件内容哈希)"""        hashes = defaultdict(list)        for file_path in self.root.rglob('*'):            if file_path.is_file():                file_hash = self._hash_file(file_path)                hashes[file_hash].append(file_path)        # 返回有重复的文件组        return {h: paths for h, paths in hashes.items() if len(paths) > 1}    def _hash_file(self, file_path, block_size=65536):        """计算文件MD5哈希"""        hasher = hashlib.md5()        with open(file_path, 'rb'as f:            for block in iter(lambda: f.read(block_size), b''):                hasher.update(block)        return hasher.hexdigest()    def find_large_files(self, min_size_mb=100):        """查找大文件"""        min_bytes = min_size_mb * 1024 * 1024        large_files = []        for file_path in self.root.rglob('*'):            if file_path.is_file():                size = file_path.stat().st_size                if size >= min_bytes:                    large_files.append((file_path, size))        return sorted(large_files, key=lambda x: x[1], reverse=True)    def generate_tree(self, max_depth=None):        """生成目录树"""        lines = [str(self.root)]        self._tree_recursive(self.root, '', lines, 0, max_depth)        return '\n'.join(lines)    def _tree_recursive(self, path, prefix, lines, depth, max_depth):        """递归生成树形结构"""        if max_depth is not None and depth >= max_depth:            return        items = sorted(path.iterdir(), key=lambda x: (x.is_file(), x.name))        for i, item in enumerate(items):            is_last = (i == len(items) - 1)            connector = '└── ' if is_last else '├── '            lines.append(prefix + connector + item.name)            if item.is_dir():                extension = '    ' if is_last else '│   '                self._tree_recursive(item, prefix + extension, lines, depth + 1, max_depth)# 使用示例analyzer = DirectoryAnalyzer('.')print("=" * 50)print("目录统计")print("=" * 50)stats = analyzer.get_statistics()print(f"文件总数: {stats['total_files']}")print(f"目录总数: {stats['total_dirs']}")print(f"总大小: {stats['total_size'] / 1024 / 1024:.2f} MB")print("\n文件类型分布:")for ext, count in sorted(stats['extensions'].items(), key=lambda x: -x[1])[:5]:    print(f"  {ext or'(无扩展名)'}{count}")print("\n" + "=" * 50)print("目录树(前2层)")print("=" * 50)print(analyzer.generate_tree(max_depth=2))

七、常见陷阱与最佳实践

7.1 陷阱1:忘记指定编码

# ❌ 错误:依赖系统默认编码(Windows可能是gbk)with open('text.txt''r'as f:    content = f.read()# ✅ 正确:始终指定编码with open('text.txt''r', encoding='utf-8'as f:    content = f.read()# ✅ 处理未知编码的文件try:    with open('text.txt''r', encoding='utf-8'as f:        content = f.read()except UnicodeDecodeError:    with open('text.txt''r', encoding='gbk', errors='ignore'as f:        content = f.read()

7.2 陷阱2:路径分隔符硬编码

# ❌ 错误:硬编码路径分隔符path = 'folder\\file.txt'  # Windowspath = 'folder/file.txt'   # Unix# ✅ 正确:使用pathlib或os.pathfrom pathlib import Pathpath = Path('folder') / 'file.txt'# 或import ospath = os.path.join('folder''file.txt')

7.3 陷阱3:裸except捕获

# ❌ 危险:捕获所有异常,包括KeyboardInterrupttry:    process()except:    pass# ✅ 正确:捕获具体异常try:    process()except ValueError as e:    logger.error(f"处理失败: {e}")# ✅ 如果确实需要捕获所有异常,至少打印信息try:    process()except Exception as e:    logger.exception("处理失败")    raise

7.4 陷阱4:文件操作中的竞态条件

# ❌ 危险:检查后再操作存在竞态条件if os.path.exists('file.txt'):    with open('file.txt''r'as f:  # 文件可能在检查后被删除        content = f.read()# ✅ 正确:直接尝试操作,捕获异常try:    with open('file.txt''r'as f:        content = f.read()except FileNotFoundError:    content = ''

7.5 最佳实践总结

场景
推荐做法
文件读写
始终使用with语句
路径操作
使用pathlib替代os.path
编码处理
始终显式指定encoding='utf-8'
异常处理
捕获具体异常,避免裸except
大文件处理
使用迭代器逐行读取
配置文件
使用JSON/YAML等标准格式

八、本章小结

核心知识点

  1. 文件读写
    :使用open()函数,注意模式和编码
  2. with语句
    :利用上下文管理器确保资源正确释放
  3. pathlib
    :面向对象的路径操作,替代os.path
  4. 异常处理
    :try/except/else/finally结构,捕获具体异常
  5. 自定义异常
    :继承Exception创建语义化的异常类

底层原理要点

  • 文件描述符
    :操作系统管理打开文件的整数标识
  • 上下文管理协议
    __enter____exit__方法
  • 异常继承体系
    :BaseException → Exception → 具体异常
  • 竞态条件
    :检查-操作模式在多线程/进程环境下的问题

九、课后练习

基础练习

  1. 文件复制工具:编写一个函数,实现文件的复制,要求显示复制进度(百分比)

  2. 文本搜索工具:编写程序,在指定目录的所有文本文件中搜索包含特定关键字的文件

  3. 异常处理练习:为以下代码添加适当的异常处理:

    def read_and_parse(filename):    with open(filename) as f:        data = json.load(f)    return data['value'] / data['count']

进阶练习

  1. 文件监控器:编写一个程序,监控指定目录,当有新文件创建时自动打印文件信息

  2. CSV处理器:实现一个CSV文件处理器,支持读取、过滤、转换和保存

  3. 安全的临时文件:使用tempfile模块创建临时文件,确保程序退出时自动清理

挑战练习

  1. 实现文件锁:使用fcntl(Unix)或msvcrt(Windows)实现跨平台的文件锁机制

  2. 内存映射文件:使用mmap模块实现大文件的高效处理


参考资源

  • Python官方文档 - 文件读写
  • Python官方文档 - pathlib
  • Python官方文档 - 异常处理
  • Python上下文管理器详解

💡 学习建议:文件操作和异常处理是编写健壮程序的基础。建议在实际项目中多使用pathlib,它比传统的os.path更加直观和安全。同时,要养成良好的异常处理习惯,捕获具体异常而非泛泛处理。


本文是《Python全栈修炼之路》系列第8篇,系列文章持续更新中,欢迎关注!

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-07-03 07:54:10 HTTP/2.0 GET : https://f.mffb.com.cn/a/501359.html
  2. 运行时间 : 0.188122s [ 吞吐率:5.32req/s ] 内存消耗:4,814.54kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=493f9bcd12a3ca0df3a44d58f37c543a
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000313s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000527s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000292s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000287s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000629s ]
  6. SELECT * FROM `set` [ RunTime:0.005685s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000645s ]
  8. SELECT * FROM `article` WHERE `id` = 501359 LIMIT 1 [ RunTime:0.022659s ]
  9. UPDATE `article` SET `lasttime` = 1783036450 WHERE `id` = 501359 [ RunTime:0.010341s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 66 LIMIT 1 [ RunTime:0.006009s ]
  11. SELECT * FROM `article` WHERE `id` < 501359 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000567s ]
  12. SELECT * FROM `article` WHERE `id` > 501359 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.004168s ]
  13. SELECT * FROM `article` WHERE `id` < 501359 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.020225s ]
  14. SELECT * FROM `article` WHERE `id` < 501359 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.013993s ]
  15. SELECT * FROM `article` WHERE `id` < 501359 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.031661s ]
0.189665s