是否可以知道有多少字节已打印到文件流(例如标准输出)?
C 中的调用程序是否可以知道它已打印到文件流(例如 stdout)中的字节数,而无需实际计算和累加 printf 的返回值?
我试图实现对使用库打印的 C 程序的输出量的控制,但库不报告它们已打印的数据量。
我对通用解决方案或特定于 Unix 的解决方案感兴趣。
Is it possible for a caller program in C to know how many bytes it has printed to a file stream such as stdout
without actually counting and adding up the return values of printf
?
I am trying to implement control of the quantity of output of a C program which uses libraries to print, but the libraries don't report the amount of data they have printed out.
I am interested in either a general solution or a Unix-specific one.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
POSIX 特定:将
stdout
重定向到文件,在完成所有写入后刷新,然后统计文件并查看st_size
(或使用ls
> 命令)。更新:您说您正在尝试控制程序的输出数量。 POSIX
head
命令可以做到这一点。如果这不令人满意,请明确说明您的要求。POSIX-specific: redirect
stdout
to a file, flush after all writing is done, then stat the file and look atst_size
(or use thels
command).Update: You say you're trying to control the quantity of output of a program. The POSIX
head
command will do that. If that's not satisfactory, then state your requirements clearly.这是一个重量级的解决方案,但以下方法可以工作:
pipe()
创建一个管道stdout
重定向到写入端管道,并关闭读取端(和旧的stdout
)stdout
(这是原始的 stdout) -基本上,其想法是生成一个子进程,并通过它传输所有输出,并让子进程在其通过时对所有数据进行计数。
使用的 IPC 的精确形式可能会有所不同 - 例如,共享内存(每一侧都有原子读/写)可以很好地实现数据的快速传输,但其他方法(例如套接字、更多管道等)也是可能的,并且提供更好的同步范围。
最棘手的部分是同步,即确保当子进程告诉父进程已写入了多少数据时,它已经处理了父进程所说的所有数据(例如,管道中没有剩余数据) 。这有多重要将取决于您的目标是什么 - 如果只需要一个大概的指示,那么您可能能够避免使用 IPC 共享内存而不执行任何显式同步;如果仅在最后需要总计,那么您可以从父级关闭 stdout,并让子级在收到
eof
通知时在共享内存中进行指示。如果您需要更频繁的读取(必须准确),那么将需要更多的复杂性,但这可以通过在共享内存中使用套接字、管道甚至 condvars/semaphores/etc 设计某种协议来实现。
It's rather a heavyweight solution, but the following will work:
pipe()
stdout
to the write-side of the pipe, and close the read side (and the oldstdout
)stdout
(which is the originalstdout
) - counting it as it goes paststdout
(which is now the pipe) as usualBasically the idea is to spawn a child process, and pipe all output through it, and have the child process count all the data as it goes through.
The precise form of IPC to use may vary - for example, shared memory (with atomic reads/writes on each side) would work well for fast transfer of data, but other methods (such as sockets, more pipes etc) are possible, and offer better scope for synchronisation.
The trickiest part is the synchronisation, i.e. ensuring that, at the time the child tells the parent how much data has been written, it has already processed all the data that the parent said (and there is none left in the pipe, for example). How important this is will depend on exactly what your aim is - if an approximate indication is all that's required, then you may be able to get away with using shared memory for IPC and not performing any explicit synchronisation; if the total is only required at the end then you can close
stdout
from the parent, and have the child indicate in the shared memory when it has received theeof
notification.If you require more frequent readouts, which must be exact, then something more copmlex will be required, but this can be achieved by designing some sort of protocol using sockets, pipes, or even condvars/semaphores/etc in the shared memory.
printf 返回写入的字节数。
把它们加起来。
printf returns the number of bytes written.
Add them up.
不知道这有多可靠,但您可以在标准输出上使用
ftell
:编辑
在 Ubuntu Precise 上检查了这一点:如果输出到控制台,它就不起作用,但如果它被重定向到文件,它就起作用。
No idea how reliable this is, but you can use
ftell
on stdout:EDIT
Checked this on Ubuntu Precise: it does not work if the output goes to the console, but does work if it is redirected to a file.