You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中如何中断单个文件读取I/O线程?以网络磁盘TIFF文件为例

实现可中断的大型TIFF文件读取操作

核心思路

cv2.imread是一次性阻塞调用,无法在读取过程中检查停止信号,因此必须改用分块读取的方式,让读取流程可以周期性响应中断指令。这里使用tifffile库替代OpenCV,它支持流式读取大型TIFF文件的分块数据,完美适配中途中断的场景。同时用threading.Event作为线程安全的停止标志,实现UI线程与读取线程的通信。

完整实现代码

import threading
import time
import tkinter as tk
import tifffile as tiff

# 全局变量管理读取状态
stop_event = None
reading_thread = None

def start_reading(path):
    global stop_event, reading_thread
    # 避免重复启动读取线程
    if reading_thread is not None and reading_thread.is_alive():
        print("读取操作已在进行中")
        return
    
    stop_event = threading.Event()
    reading_thread = threading.Thread(target=read_tiff, args=(path, stop_event))
    reading_thread.start()

def read_tiff(path, stop_event):
    start = time.time()
    print('开始读取文件\n')
    # 用tifffile以分块方式打开文件
    with tiff.TiffFile(path) as tif:
        img = tif.asarray(memmap=True)  # 内存映射,不一次性加载全部数据
        height, width = img.shape[:2]
        # 定义分块大小(可根据实际调整)
        block_size = 512
        # 逐块读取并检查停止信号
        for y in range(0, height, block_size):
            for x in range(0, width, block_size):
                if stop_event.is_set():
                    print('读取已中断,耗时: %.3f' % (time.time() - start))
                    return
                # 读取当前块
                block = img[y:y+block_size, x:x+block_size]
                # 这里可以添加块数据的处理逻辑(如预览、存储等)
                print(f"已读取块 [{y}:{y+block_size}, {x}:{x+block_size}]")
    
    print('读取完成,耗时: %.3f' % (time.time() - start))

def stop_reading():
    global stop_event, reading_thread
    if stop_event is not None and reading_thread is not None and reading_thread.is_alive():
        stop_event.set()
        # 等待线程结束(可选,根据需求决定是否阻塞UI)
        reading_thread.join()
        print("读取线程已终止")
    else:
        print("没有正在进行的读取操作")

file = 'random.tiff'
root = tk.Tk()
root.title("可中断TIFF读取工具")

start_button = tk.Button(root, text="开始读取", command=lambda: start_reading(file))
start_button.pack(pady=5)

stop_button = tk.Button(root, text="停止读取", command=stop_reading)
stop_button.pack(pady=5)

root.mainloop()

关键细节说明

  • 分块读取与内存映射:tif.asarray(memmap=True)创建内存映射数组,不会一次性把整个大文件加载到内存,而是按需读取分块,既节省内存又能插入中断检查。
  • 停止信号机制:threading.Event是线程安全的标志,主线程点击停止按钮时调用stop_event.set(),读取线程在每次读取分块后检查该标志,一旦触发就立即终止流程。
  • 线程状态管理:通过全局变量reading_thread跟踪当前读取线程,避免重复启动;停止时调用join()确保线程安全终止。

内容的提问来源于stack exchange,提问作者vaindru

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 05:13:32