我该如何在C++中读写设备?设备位于/dev/ttyPA1
。
我考虑使用fstream,但我无法知道是否可以在不阻止应用程序的情况下读取设备的输出。
我的目标是创建一个应用程序,在其中将某些内容写入终端并将其发送到/dev/ttyPA1
。如果设备有返回值,则从设备读取并显示在屏幕上。如果没有,则提示用户再次向设备写入内容。
我该如何实现这个目标?
open(2)
、read(2)
和 write(2)
来读写设备(完成后别忘了使用close(2)
函数)。你也可以使用 C 标准库函数(如fopen(3)
等)或 C++ 文件流类,但如果你这么做,你几乎肯定要禁用缓冲(对于标准I/O,使用setvbuf(3)
,对于文件流,使用outFile.rdbuf()->pubsetbuf(0, 0)
)。select(2)
来测试是否能够从文件描述符中读取或写入而不发生阻塞(如果不可能,就不应该这样做)。或者,你可以在文件描述符上使用O_NONBLOCK
标志来打开文件(或在打开后使用fcntl(2)
设置标志),使其成为非阻塞的;然后,任何调用read(2)
或write(2)
如果会阻塞,将立即失败并显示错误EWOULDBLOCK
。// Open the device in non-blocking mode
int fd = open("/dev/ttyPA1", O_RDWR | O_NONBLOCK);
if(fd < 0)
; // handle error
// Try to write some data
ssize_t written = write(fd, "data", 4);
if(written >= 0)
; // handle successful write (which might be a partial write!)
else if(errno == EWOULDBLOCK)
; // handle case where the write would block
else
; // handle real error
// Reading data is similar
你可以使用fstream
,但是你需要查找设备的规格说明以确定它希望收到数据的方式。某些设备使用ASCII数据就可以了,而其他设备则需要特定的二进制数据位/字节序列。您还可能需要编写自定义序列化对象,重载用于编写数据的operator<<
和operator>>
函数。否则,您可以使用read()
和write()
方法从/向程序中分配的缓冲区数组读取/编写原始二进制数据。
编辑:如果您担心阻塞行为,那么您有两个选择。您要么必须使用POSIX API,并使用poll()
或select()
检查已打开的文件描述符以查看是否有可用数据,要么您将不得不将任何文件写入或读取调用放在一组单独的线程中,这些线程可以基本上充当异步读/写操作。因此,您基本上会向读者/编写者线程发送消息,该线程如有需要会在fstream
调用上阻塞,但是您的程序的其余部分仍然可以继续运行。但是,如果您的程序没有设计用于线程,则POSIX API将是唯一的方法。
fstream::read()
函数获取字节并将其加载到内部分配的缓冲区中,这基本上是在 C 中使用 read()
和使用 open()
分配的文件描述符时使用的相同方法。否则,你可以创建一些对象来管理自己的内部内存缓冲区,并重载 operator>>
函数以与你的自定义读取器对象一起使用。 - Jason
open()
和相关函数吗? - Lightness Races in Orbit