[android-developers] Re: How to block a BufferedReader when no input is available?

2010-12-19 Thread Bob Kerns
I figured it'd be something like that. Confusion can be
contagious... :=)

Using a byte array stream says you know how much data you have up
front. You can't grow arrays in Java.

The growable equivalent would be a PipedInputStream/PipedOutputStream
pair, and read operates there as you'd expect, blocking the input if
no further output is available. And write() blocks until space is
available to write, too.

On Dec 19, 12:33 pm, Kostya Vasilyev  wrote:
> Bob,
>
> Yes, you're right, that's how it works.
>
> Somehow I got the impression that the OP was using a byte array stream,
> which does report end of input as soon as the end of its byte array is
> reached.
>
> Rereading the post, I realized that he never actually said he was using
> a byte array stream. It must have been the "constantly growing" that
> made me think of a byte array.
>
> Thanks.
>
> -- Kostya
>
> 19.12.2010 22:58, Bob Kerns пишет:
>
>
>
>
>
>
>
>
>
> > You're missing something. Surprisingly, so are Dan and Kostya! :=)
>
> > 1) use of notify/wait does not involve sleep in any way, shape, or
> > form. It is, in fact, exactly what you're asking for -- but at a very
> > low level that you don't even need to worry about here.
>
> > 2) The normal way to read, blocking until input is available, is to
> > call one of the read() methods on the input stream. Under some
> > circumstances, it is possible for a read on certain streams to return
> > with zero bytes of data, but that would be an unusual circumstance
> > (like, for example, a write to a pipe with zero bytes of data). But
> > that will still be in response to some data, not due to the stream
> > being dry. You're right that this is a key part of many I/O systems --
> > including Java. Really, why did you think otherwise?
>
> > Quoting from the documentation for the read() method:
> > "This method blocks until input data is available, end of file is
> > detected, or an exception is thrown." -- JDK
> > "Blocks until one byte has been read, the end of the source stream is
> > detected or an exception is thrown." -- ADK
>
> > BufferedReader.readLine() calls read() on the underlying Reader.
> > InputStreamReader calls read() on the underlying stream. Just get rid
> > of your outer do/while loop and associated Thread.sleep() call.
>
> > Here's a little demo program:
>
> > import java.io.BufferedReader;
> > import java.io.IOException;
> > import java.io.InputStreamReader;
>
> > public class Run {
> >      public static void main(String...args) throws IOException,
> > InterruptedException {
> >          if (args.length == 0) {
> >              System.err.println("Usage: java " + Run.class.getName() +
> > "");
> >              System.exit(-1);
> >          }
> >          Process process = new
> > ProcessBuilder(args).redirectErrorStream(true).start();
> >          BufferedReader in = new BufferedReader(new
> > InputStreamReader(process.getInputStream(), "UTF-8"));
> >          String line;
> >          while ((line = in.readLine()) != null) {
> >              System.out.println(line);
> >          }
> >          System.out.println("All done; trying more reads to demonstrate
> > further.");
> >          boolean readMore = false;
> >          while ((line = in.readLine()) != null) {
> >                  readMore = true;
> >                  System.out.println("MORE: " + line);
> >          }
> >          if (readMore) {
> >              System.out.println("Stream did not immediately fail after
> > returning null");
> >          } else {
> >              System.out.println("Stream did not allow additional reads
> > after returning null.");
> >          }
> >      }
> > }
>
> > You can call this on a script that alternatively outputs and sleeps,
> > such as this one for windows:
>
> > run.bat:
> > @for /L %%i in (0, 1, 10) do @(
> >    echo This is step %%i
> >    sleep 6
> > )
>
> > On Dec 19, 9:37 am, DulcetTone  wrote:
> >> I don't think any of these solutions help, as I did not write the
> >> writer thread and cannot alter its code.
>
> >> Unless I am missing something, use of notify/wait would only move the
> >> sleep() to another thread, achieving nothing.
>
> >> Is there no intrinsic, system-based means of having a read block until
> >> the stream is closed (rather than having just temporarily run dry) or
> >> has more data to offer?  This is a key part of many I/O systems, yes?
>
> >> tone
>
> >> On Dec 19, 9:22 am, Kostya Vasilyev  wrote:
>
> >>> Use Java thread synchronization:
> >>>http://www.javamex.com/tutorials/synchronization_wait_notify.shtml
> >>> Have the reader thread "wait" when there is no data and the writer
> >>> thread "notify" the reader when more data is available (and when it
> >>> should exit its processing loop).
> >>> -- Kostya
> >>> 19.12.2010 16:38, DulcetTone пишет:
>  I have code in a worker thread that needs to efficiently read a
>  constantly-growing input stream from a process.
>  The issue is that the present design uses a sleep() for a short period
> 

Re: [android-developers] Re: How to block a BufferedReader when no input is available?

2010-12-19 Thread Kostya Vasilyev

Bob,

Yes, you're right, that's how it works.

Somehow I got the impression that the OP was using a byte array stream, 
which does report end of input as soon as the end of its byte array is 
reached.


Rereading the post, I realized that he never actually said he was using 
a byte array stream. It must have been the "constantly growing" that 
made me think of a byte array.


Thanks.

-- Kostya

19.12.2010 22:58, Bob Kerns пишет:

You're missing something. Surprisingly, so are Dan and Kostya! :=)

1) use of notify/wait does not involve sleep in any way, shape, or
form. It is, in fact, exactly what you're asking for -- but at a very
low level that you don't even need to worry about here.

2) The normal way to read, blocking until input is available, is to
call one of the read() methods on the input stream. Under some
circumstances, it is possible for a read on certain streams to return
with zero bytes of data, but that would be an unusual circumstance
(like, for example, a write to a pipe with zero bytes of data). But
that will still be in response to some data, not due to the stream
being dry. You're right that this is a key part of many I/O systems --
including Java. Really, why did you think otherwise?

Quoting from the documentation for the read() method:
"This method blocks until input data is available, end of file is
detected, or an exception is thrown." -- JDK
"Blocks until one byte has been read, the end of the source stream is
detected or an exception is thrown." -- ADK

BufferedReader.readLine() calls read() on the underlying Reader.
InputStreamReader calls read() on the underlying stream. Just get rid
of your outer do/while loop and associated Thread.sleep() call.

Here's a little demo program:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Run {
 public static void main(String...args) throws IOException,
InterruptedException {
 if (args.length == 0) {
 System.err.println("Usage: java " + Run.class.getName() +
"");
 System.exit(-1);
 }
 Process process = new
ProcessBuilder(args).redirectErrorStream(true).start();
 BufferedReader in = new BufferedReader(new
InputStreamReader(process.getInputStream(), "UTF-8"));
 String line;
 while ((line = in.readLine()) != null) {
 System.out.println(line);
 }
 System.out.println("All done; trying more reads to demonstrate
further.");
 boolean readMore = false;
 while ((line = in.readLine()) != null) {
 readMore = true;
 System.out.println("MORE: " + line);
 }
 if (readMore) {
 System.out.println("Stream did not immediately fail after
returning null");
 } else {
 System.out.println("Stream did not allow additional reads
after returning null.");
 }
 }
}

You can call this on a script that alternatively outputs and sleeps,
such as this one for windows:

run.bat:
@for /L %%i in (0, 1, 10) do @(
   echo This is step %%i
   sleep 6
)

On Dec 19, 9:37 am, DulcetTone  wrote:

I don't think any of these solutions help, as I did not write the
writer thread and cannot alter its code.

Unless I am missing something, use of notify/wait would only move the
sleep() to another thread, achieving nothing.

Is there no intrinsic, system-based means of having a read block until
the stream is closed (rather than having just temporarily run dry) or
has more data to offer?  This is a key part of many I/O systems, yes?

tone

On Dec 19, 9:22 am, Kostya Vasilyev  wrote:








Use Java thread synchronization:
http://www.javamex.com/tutorials/synchronization_wait_notify.shtml
Have the reader thread "wait" when there is no data and the writer
thread "notify" the reader when more data is available (and when it
should exit its processing loop).
-- Kostya
19.12.2010 16:38, DulcetTone пишет:

I have code in a worker thread that needs to efficiently read a
constantly-growing input stream from a process.
The issue is that the present design uses a sleep() for a short period
if there is no input presently available, and I'd like the attempt to
read the input stream simply *block* so it magically awakes when more
input is available.  I fear this will mean a small hit on phone
responsiveness.
How does one alter code from this form to do such a thing?
BufferedReader bufferedReader =
  new BufferedReader(new
InputStreamReader(process.getInputStream()));
  do {
  String line;
  while ((line = bufferedReader.readLine()) != null) {
// new input would be processed here
  }
  Thread.sleep(500); // TODO: make this go away
  } while (true);

--
Kostya Vasilyev -- WiFi Manager + pretty widget --http://kmansoft.wordpress.com



--
Kostya Vasilyev -- WiFi Manager + pretty widget -- http://kmansoft.wordpress.com

--
You received this me

[android-developers] Re: How to block a BufferedReader when no input is available?

2010-12-19 Thread Bob Kerns
You're missing something. Surprisingly, so are Dan and Kostya! :=)

1) use of notify/wait does not involve sleep in any way, shape, or
form. It is, in fact, exactly what you're asking for -- but at a very
low level that you don't even need to worry about here.

2) The normal way to read, blocking until input is available, is to
call one of the read() methods on the input stream. Under some
circumstances, it is possible for a read on certain streams to return
with zero bytes of data, but that would be an unusual circumstance
(like, for example, a write to a pipe with zero bytes of data). But
that will still be in response to some data, not due to the stream
being dry. You're right that this is a key part of many I/O systems --
including Java. Really, why did you think otherwise?

Quoting from the documentation for the read() method:
"This method blocks until input data is available, end of file is
detected, or an exception is thrown." -- JDK
"Blocks until one byte has been read, the end of the source stream is
detected or an exception is thrown." -- ADK

BufferedReader.readLine() calls read() on the underlying Reader.
InputStreamReader calls read() on the underlying stream. Just get rid
of your outer do/while loop and associated Thread.sleep() call.

Here's a little demo program:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Run {
public static void main(String...args) throws IOException,
InterruptedException {
if (args.length == 0) {
System.err.println("Usage: java " + Run.class.getName() +
" ");
System.exit(-1);
}
Process process = new
ProcessBuilder(args).redirectErrorStream(true).start();
BufferedReader in = new BufferedReader(new
InputStreamReader(process.getInputStream(), "UTF-8"));
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
System.out.println("All done; trying more reads to demonstrate
further.");
boolean readMore = false;
while ((line = in.readLine()) != null) {
readMore = true;
System.out.println("MORE: " + line);
}
if (readMore) {
System.out.println("Stream did not immediately fail after
returning null");
} else {
System.out.println("Stream did not allow additional reads
after returning null.");
}
}
}

You can call this on a script that alternatively outputs and sleeps,
such as this one for windows:

run.bat:
@for /L %%i in (0, 1, 10) do @(
  echo This is step %%i
  sleep 6
)

On Dec 19, 9:37 am, DulcetTone  wrote:
> I don't think any of these solutions help, as I did not write the
> writer thread and cannot alter its code.
>
> Unless I am missing something, use of notify/wait would only move the
> sleep() to another thread, achieving nothing.
>
> Is there no intrinsic, system-based means of having a read block until
> the stream is closed (rather than having just temporarily run dry) or
> has more data to offer?  This is a key part of many I/O systems, yes?
>
> tone
>
> On Dec 19, 9:22 am, Kostya Vasilyev  wrote:
>
>
>
>
>
>
>
> > Use Java thread synchronization:
>
> >http://www.javamex.com/tutorials/synchronization_wait_notify.shtml
>
> > Have the reader thread "wait" when there is no data and the writer
> > thread "notify" the reader when more data is available (and when it
> > should exit its processing loop).
>
> > -- Kostya
>
> > 19.12.2010 16:38, DulcetTone пишет:
>
> > > I have code in a worker thread that needs to efficiently read a
> > > constantly-growing input stream from a process.
>
> > > The issue is that the present design uses a sleep() for a short period
> > > if there is no input presently available, and I'd like the attempt to
> > > read the input stream simply *block* so it magically awakes when more
> > > input is available.  I fear this will mean a small hit on phone
> > > responsiveness.
>
> > > How does one alter code from this form to do such a thing?
>
> > > BufferedReader bufferedReader =
> > >                  new BufferedReader(new
> > > InputStreamReader(process.getInputStream()));
>
> > >              do {
> > >                  String line;
> > >                  while ((line = bufferedReader.readLine()) != null) {
> > > // new input would be processed here
> > >                  }
> > >                  Thread.sleep(500); // TODO: make this go away
> > >              } while (true);
>
> > --
> > Kostya Vasilyev -- WiFi Manager + pretty widget 
> > --http://kmansoft.wordpress.com

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en


Re: [android-developers] Re: How to block a BufferedReader when no input is available?

2010-12-19 Thread Kostya Vasilyev

19.12.2010 20:37, DulcetTone пишет:

I don't think any of these solutions help, as I did not write the
writer thread and cannot alter its code.


Ah.


Unless I am missing something, use of notify/wait would only move the
sleep() to another thread, achieving nothing.


It would achieve quite a bit, but it requires making changes to the 
writing side, which, as you said, is out of your control.



Is there no intrinsic, system-based means of having a read block until
the stream is closed (rather than having just temporarily run dry) or
has more data to offer?  This is a key part of many I/O systems, yes?


Non-blocking IO is, as a whole, an afterthought in Java (they had to 
reinvent it for NIO, and managed to forget SSL in the process).


You could try using InputStream.available(). Now sure how well it would 
work with a BufferedStreamReader, so I'd recommend trying to make the 
basic processing loop work first, and only then add the reader or your 
own line breaking code.


-- Kostya


tone


On Dec 19, 9:22 am, Kostya Vasilyev  wrote:

Use Java thread synchronization:

http://www.javamex.com/tutorials/synchronization_wait_notify.shtml

Have the reader thread "wait" when there is no data and the writer
thread "notify" the reader when more data is available (and when it
should exit its processing loop).

-- Kostya

19.12.2010 16:38, DulcetTone пишет:










I have code in a worker thread that needs to efficiently read a
constantly-growing input stream from a process.
The issue is that the present design uses a sleep() for a short period
if there is no input presently available, and I'd like the attempt to
read the input stream simply *block* so it magically awakes when more
input is available.  I fear this will mean a small hit on phone
responsiveness.
How does one alter code from this form to do such a thing?
BufferedReader bufferedReader =
  new BufferedReader(new
InputStreamReader(process.getInputStream()));
  do {
  String line;
  while ((line = bufferedReader.readLine()) != null) {
// new input would be processed here
  }
  Thread.sleep(500); // TODO: make this go away
  } while (true);

--
Kostya Vasilyev -- WiFi Manager + pretty widget --http://kmansoft.wordpress.com



--
Kostya Vasilyev -- WiFi Manager + pretty widget -- http://kmansoft.wordpress.com

--
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en


[android-developers] Re: How to block a BufferedReader when no input is available?

2010-12-19 Thread DulcetTone
I don't think any of these solutions help, as I did not write the
writer thread and cannot alter its code.

Unless I am missing something, use of notify/wait would only move the
sleep() to another thread, achieving nothing.

Is there no intrinsic, system-based means of having a read block until
the stream is closed (rather than having just temporarily run dry) or
has more data to offer?  This is a key part of many I/O systems, yes?

tone


On Dec 19, 9:22 am, Kostya Vasilyev  wrote:
> Use Java thread synchronization:
>
> http://www.javamex.com/tutorials/synchronization_wait_notify.shtml
>
> Have the reader thread "wait" when there is no data and the writer
> thread "notify" the reader when more data is available (and when it
> should exit its processing loop).
>
> -- Kostya
>
> 19.12.2010 16:38, DulcetTone пишет:
>
>
>
>
>
>
>
>
>
> > I have code in a worker thread that needs to efficiently read a
> > constantly-growing input stream from a process.
>
> > The issue is that the present design uses a sleep() for a short period
> > if there is no input presently available, and I'd like the attempt to
> > read the input stream simply *block* so it magically awakes when more
> > input is available.  I fear this will mean a small hit on phone
> > responsiveness.
>
> > How does one alter code from this form to do such a thing?
>
> > BufferedReader bufferedReader =
> >                  new BufferedReader(new
> > InputStreamReader(process.getInputStream()));
>
> >              do {
> >                  String line;
> >                  while ((line = bufferedReader.readLine()) != null) {
> > // new input would be processed here
> >                  }
> >                  Thread.sleep(500); // TODO: make this go away
> >              } while (true);
>
> --
> Kostya Vasilyev -- WiFi Manager + pretty widget 
> --http://kmansoft.wordpress.com

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en


[android-developers] Re: How to block a BufferedReader when no input is available?

2010-12-19 Thread DanH
(Of course, what you need is a loop of !ready ->sleep(nnn))

On Dec 19, 8:09 am, DanH  wrote:
> ready?
>
> On Dec 19, 7:38 am, DulcetTone  wrote:
>
> > I have code in a worker thread that needs to efficiently read a
> > constantly-growing input stream from a process.
>
> > The issue is that the present design uses a sleep() for a short period
> > if there is no input presently available, and I'd like the attempt to
> > read the input stream simply *block* so it magically awakes when more
> > input is available.  I fear this will mean a small hit on phone
> > responsiveness.
>
> > How does one alter code from this form to do such a thing?
>
> > BufferedReader bufferedReader =
> >                 new BufferedReader(new
> > InputStreamReader(process.getInputStream()));
>
> >             do {
> >                 String line;
> >                 while ((line = bufferedReader.readLine()) != null) {
> > // new input would be processed here
> >                 }
> >                 Thread.sleep(500); // TODO: make this go away
> >             } while (true);

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en


[android-developers] Re: How to block a BufferedReader when no input is available?

2010-12-19 Thread DanH
(But, of course, ready causes the thread to wait -- not something the
main thread should do.)

On Dec 19, 7:38 am, DulcetTone  wrote:
> I have code in a worker thread that needs to efficiently read a
> constantly-growing input stream from a process.
>
> The issue is that the present design uses a sleep() for a short period
> if there is no input presently available, and I'd like the attempt to
> read the input stream simply *block* so it magically awakes when more
> input is available.  I fear this will mean a small hit on phone
> responsiveness.
>
> How does one alter code from this form to do such a thing?
>
> BufferedReader bufferedReader =
>                 new BufferedReader(new
> InputStreamReader(process.getInputStream()));
>
>             do {
>                 String line;
>                 while ((line = bufferedReader.readLine()) != null) {
> // new input would be processed here
>                 }
>                 Thread.sleep(500); // TODO: make this go away
>             } while (true);

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en


[android-developers] Re: How to block a BufferedReader when no input is available?

2010-12-19 Thread DanH
ready?

On Dec 19, 7:38 am, DulcetTone  wrote:
> I have code in a worker thread that needs to efficiently read a
> constantly-growing input stream from a process.
>
> The issue is that the present design uses a sleep() for a short period
> if there is no input presently available, and I'd like the attempt to
> read the input stream simply *block* so it magically awakes when more
> input is available.  I fear this will mean a small hit on phone
> responsiveness.
>
> How does one alter code from this form to do such a thing?
>
> BufferedReader bufferedReader =
>                 new BufferedReader(new
> InputStreamReader(process.getInputStream()));
>
>             do {
>                 String line;
>                 while ((line = bufferedReader.readLine()) != null) {
> // new input would be processed here
>                 }
>                 Thread.sleep(500); // TODO: make this go away
>             } while (true);

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en