Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check whether stream has any data?

Tags:

php

This what I'm trying to do:

$output = '';
$stream = popen("some-long-running-command 2>&1", 'r');
while (!feof($stream)) {
  $meta = stream_get_meta_data($stream);
  if ($meta['unread_bytes'] > 0) {
    $line = fgets($stream);
    $output .= $line;
  }
  echo ".";
}
$code = pclose($stream);

Looks like this code is not correct, since it gets stuck at the call to stream_get_meta_data(). What is the right way to check whether the stream has some data to read? The whole point here is to avoid locking at fgets().

like image 585
yegor256 Avatar asked Dec 19 '12 13:12

yegor256


People also ask

How do I know if a stream is empty?

You have to consume the stream to find out if it's empty. That's the point of Stream's semantics (laziness). To check that the stream is not empty you have to attempt to consume at least one element. At that point the stream has lost its "virginity" and cannot be consumed again from the start.

Do Streams store data?

Streams do not store data; rather, they provide data from a source such as a collection, array, or IO channel. Streams do no modify the data source. They transform data into a new stream, for instance, when doing a filtering operation. Many stream operations are lazily-evaluated.

How do I check if InputStream is not empty?

No, you can't. InputStream is designed to work with remote resources, so you can't know if it's there until you actually read from it. You may be able to use a java.

Is stream a data structure?

In contrast, a stream is a conceptually fixed data structure in which elements are computed on demand. Using the Collection interface requires iteration to be done by the user (for example, using the enhanced for loop called foreach ); this is called external iteration.


1 Answers

The correct way to do this is with stream_select():

$stream = popen("some-long-running-command 2>&1", 'r');
while (!feof($stream)) {
  $r = array($stream);
  $w = $e = NULL;

  if (stream_select($r, $w, $e, 1)) {
    // there is data to be read
  }
}
$code = pclose($stream);

One thing to note though (I'm not sure about this) is that it may be the feof() check that is "blocking" - it may be that the loop never ends because the child process does not close its STDOUT descriptor.

like image 141
DaveRandom Avatar answered Sep 22 '22 18:09

DaveRandom