开发者

Is it possible to know how many bytes have been printed to a file stream such as standard output?

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 pri开发者_JS百科ntf?

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.


POSIX-specific: redirect stdout to a file, flush after all writing is done, then stat the file and look at st_size (or use the ls 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.


It's rather a heavyweight solution, but the following will work:

  1. Create a pipe by calling pipe()
  2. Spawn a child process
  3. In the parent: redirect stdout to the write-side of the pipe, and close the read side (and the old stdout)
  4. In the child: keep reading from the read side of the pipe, and copying the data to the inherited stdout (which is the original stdout) - counting it as it goes past
  5. In the parent, keep writing to stdout (which is now the pipe) as usual
  6. Use some form of IPC to communicate the result of the count from the child to the parent.

Basically 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 the eof 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 returns the number of bytes written.

Add them up.


No idea how reliable this is, but you can use ftell on stdout:

long int start = ftell(stdout);
printf("abcdef\n");
printf("%ld\n", ftell(stdout) - start); // >> 7

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.

$ ./a.out 
abcdef
0
$ ./a.out >tt
$ cat tt
abcdef
7
$ echo `./a.out`
abcdef 0
$ echo `cat tt`
abcdef 7
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜