首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在屏幕上记录数据时用Python读取文件

在屏幕上记录数据时用Python读取文件
EN

Stack Overflow用户
提问于 2010-09-14 14:13:34
回答 3查看 992关注 0票数 2

背景

为了从逻辑控制器捕获数据,我使用屏幕作为终端仿真器,并通过MacBook连接KeySpan美国-19 Serial串行适配器。我创建了下面的bash脚本,以便输入talk2controller <filename>,其中文件名是数据文件的名称。

代码语言:javascript
复制
#!/bin/bash
if [ -z "$1" ]; then
    echo Please provide the filename to save the logfile
    exit
fi
LOGFILE=$1
echo "logfile $1" > screenrc        # Set the logfile filename
echo "logfile flush 1" >> screenrc  # Wait 1 sec before flushing buffer to filesystem
screen -L -c screenrc /dev/tty.KeySerial1 19200

我已经更改了日志文件的文件名,并将等待从默认的10秒更改为1秒,然后将日志文件缓冲区刷新到文件系统。我将这些命令保存到screenrc中。然后我打电话给屏幕:

  1. 启用-L - logging
  2. -c screenrc -覆盖默认配置文件
  3. /dev/tty.KeySerial1 19200 -使用波特率19200与串口对话

我记录的每个测试大约需要3-6分钟,包含速度、加速度和位置信息.我会知道基于加速率的测试是有效的。目前,我正在等待测试之后,然后运行Python脚本来绘制速度、加速和位置,以查看测试是否有效,然后再转到下一个测试。

为了节省时间,我更喜欢在测试进行一半的时候绘制数据,而数据仍在被捕获。

问题

在我看来,在仍在捕获更多数据的情况下,绘制数据有两种选择:

  • 选项1:使用屏幕记录数据,并让Python脚本读取部分日志文件。
    • 问题1:当屏幕仍在向其写入数据时,脚本读取日志文件时会有什么顾虑?

  • 选项2:从使用屏幕切换到使用pySerial。但是,在测试期间绘制数据比简单地在测试期间捕获数据要低一些。我不能让代码的绘图部分中的异常导致数据日志记录失败。这就是屏幕的伟大之处--它只是转储数据,而不尝试做任何其他事情。
    • 问题2:如果我切换到pySerial,我可以运行两个线程来减少代码的绘图部分不影响数据捕获代码的可能性吗?这能给我买点什么吗?

问题3:还有更好的选择吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-09-17 00:26:32

选项1和2都会起作用,但是哦,天哪,在一切美好的事情的名义下,避免使用线程来实现这一点!最后,您将遇到两种情况中最糟糕的情况:锁定问题,而图形化线程中的异常无论如何也会扼杀整个程序(包括日志线程)。正如其他人所提到的,为此使用两个单独的进程是可以的。为此,screen是一个奇怪的工具选择,在python中手工编写代码也是如此。我只是将talk2controller脚本重写为这个琐碎的脚本:

代码语言:javascript
复制
stty -F /dev/tty.KeySerial1 19200 raw
cat </dev/tty.KeySerial1 >logfile

(如果希望脚本的每一次运行都附加到文件中,也可以使用>>logfile,而不是从头重写。)

另一个问题是,只要其他人正在写入文件,让程序从文件中读取是否可以。这个问题的一个更具体的版本是:如果在尝试阅读日志时,日志的一行是半写的呢?

答案是:你被允许这样做,但你是对的,你不能保证一句话在你读的时候不会写一半。(如果您为catscreen编写自己的替代程序,则实际上可以通过始终使用os.read()而不是sys.stdout.write()print写入文件来提供这种保证。)

然而,无论如何,这种保证是不需要的。您只需在读取文件时小心,就不会有任何问题。本质上,不完整的行就是不以\n换行符结尾的行。因此:

代码语言:javascript
复制
for line in open('logfile'):
    if not line.endswith('\n'): break
    ...handle valid line...

由于\n字符是日志中每一行所写的最后一件东西,所以您肯定知道,如果您读取\n字符,那么在正确写入它之前的所有内容都是正确的。

票数 3
EN

Stack Overflow用户

发布于 2010-09-14 18:24:49

我认为选项1是完全可行的,因为您可以很容易地在只读管道中使用screen“尾部”日志文件,这样在screen仍在写入日志文件时不会对其造成损害。在跟踪文件时,只要在日志文件中检测到新的日志事件,就可以执行指定的操作。

如果您很好奇,并且希望看到一些工作代码,我的一个个人项目将使用此功能。该项目名为thrasher-日志下降,其核心是logdrop.py。基本流程是:

  • do_tail()尾随文件
  • 使用tail_lines()监视日志事件
  • 使用handle_line()对事件执行操作
票数 1
EN

Stack Overflow用户

发布于 2010-09-14 18:56:07

我想说的是,选择2是最好的选择。当您接收到每个字节的输入时,您可以完全控制它的处理方式。您可以有一个非常简单的Python脚本,它只是在读取数据时将数据写入磁盘。您的绘图代码可以在第一个fork()创建的完全独立的进程中运行。要将数据从一个写入另一个进程,您可以:(a)让第一个进程也写入socketpair()或其他IPC机制;或者(b)将输出文件对象配置为行缓冲--使其在写入每一行后显式同步--并监视第二个进程中的新内容。

选项1的问题在于,您无法控制screen的缓冲行为。您可以监视它的日志文件中的新内容,但是您的日志代码需要准备好同时处理不完整的行和大量的数据块。根据确切的缓冲行为,在screen进程退出之前,您甚至可能根本看不到任何数据!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3709698

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档