繁体   English   中英

如何创建一个非阻塞生成器来读取文件?

[英]How to create a non-blocking generator to read a file?

我正在尝试创建一个文件生成器,它允许我继续逐行读取文件(CSV),并在新行添加到文件时继续运行(如连续日志),但也保持等待/运行在日志中找不到新行时的背景。

我试过使用aiofiles ,但我不知道如何从我的同步功能/主 function 运行异步 function。 然后我尝试了trio ,并使用以下代码可以读取文件中的行。

async def open_file(filepath):
    with open(filepath, newline='') as f:
        first_line = True
        _reader = csv.reader(f, lineterminator='\n')
        for row in _reader:
            if row:
                # skip header row
                if first_line:
                    first_line = False
                else:
                    print(tuple(row)) # yield tuple(row) here gives the error stated below
            else:
                await trio.sleep(1)

trio.run(open_file, 'products.csv')

但是脚本在读取行后停止,并且不会在后台等待更多行 当我将print(row)替换为yield tuple(row) (实际上将返回一个生成器)时,我收到错误TypeError: start_soon expected an async function but got an async generator <async_generator object open_file at 0x1050944d0>

所以print行工作正常,但yield不是

我怎样才能解决这个问题? 另外,这将有助于并行读取行吗?
更新
请不要说我必须使用csv.reader来读取行,因为某些行包含\n ,这是正确读取记录的唯一方法。

迭代器对您的情况没有帮助,因为迭代器在到达文件末尾时立即停止

您可能会在以下模块中查找类似的功能 - https://github.com/kasun/python-tail/blob/master/tail.py

    def follow(filename):
        with open(filename) as file_:
            file_.seek(0,2)  # Remove it if you need to scan file from the beginning
            while True:
                curr_position = file_.tell()
                line = file_.readline()
                if not line:
                    file_.seek(curr_position)
                    yield None
                else:
                    yield line

然后,您可以创建一个生成器,如果行尚未准备好,则生成 None ;如果文件中有下一行可用,则生成字符串。 使用next() function 您可以以非阻塞方式逐行获取。

以下是你如何使用它:

non_blocking_reader = follow("my_file.txt")

# do something
line = next(non_blocking_reader)
if line is not None:  # You need to distinguish None from empty string, so use `is not` not just `if line:`
    # do something else
# do something else
next_line = next(non_blocking_reader)
# ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM