Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-12-08 Thread Chris Hegarty
For completeness, here is the finalized spec that we intend to submit 
for approval. Just some minor rewording and grammaticality amendments 
over the previous.


   /**
 * Reads all bytes from this input stream and writes the bytes to 
the given
 * output stream in the order that they are read.  On return, this 
input

 * stream will be at end of stream.
 * p
 * This method may block indefinitely reading from the input stream,
 * or writing to the output stream. The behavior for the case that the
 * input and/or output stream is iasynchronously closed/i, or the
 * thread interrupted during the transfer, is highly input and 
output stream

 * specific, and therefore not specified.
 * p
 * If an I/O error occurs reading from the input stream or writing to
 * the output stream, then it may do so after some bytes have been 
read or
 * written. Consequently the input stream may not be at end of 
stream and
 * one, or both, streams may be in an inconsistent state. It is 
strongly
 * recommended that both streams be promptly closed if an I/O error 
occurs.

 *
 * @param  out the output stream, non-null
 * @return the number of bytes transferred
 * @throws IOException if an I/O error occurs when reading or writing
 * @throws NullPointerException  if {@code out} is {@code null}
 *
 * @since 1.9
 */
public long transferTo(OutputStream out) throws IOException { ... }

-Chris.


On 05/12/14 18:29, Chris Hegarty wrote:


On 5 Dec 2014, at 17:28, Patrick Reinhart patr...@reini.net wrote:


Hi Chris,


Am 05.12.2014 um 17:36 schrieb Chris Hegarty chris.hega...@oracle.com:

On 05/12/14 15:59, Alan Bateman wrote:

On 05/12/2014 15:38, Chris Hegarty wrote:

The addition of a copyTo method to java.io.InputStream is binary
compatible [1], but it may, in some cases, be source incompatible. I
believe the benefits of this approach out weigh the potential source
incompatibility, but it will be for the spec gods, the CCC, to have
final say.

Here is what I propose. Let's take just InputStream.copyTo and bring
it, by itself, to a conclusion. And then revisit each of the
additional useful/convenience methods on their own merit.

I think the approach is good. An alternative name to consider is
transferTo. For the javadoc then you can make it clear that the
InputStream is at EOF when the method completes. I don't think the
javadoc needs to say that the OutputStream should be closed promptly
(think cat a b c  d).


Right. Updated spec:

/**
 * Reads all remaining bytes from this input stream and writes them to
 * the given output stream.  On return, this input stream will be at end of
 * stream.
 * p
 * This method may block indefinitely reading from the input stream,
 * or writing to the output stream. The behavior for the case that the
 * input and/or output stream is iasynchronously closed/i, or the
 * thread interrupted during the copy, is highly input and output stream
 * specific, and therefore not specified.
 * p
 * If an I/O error occurs reading from the input stream or writing to
 * the output stream, then it may do so after some bytes have been read or
 * written. Consequently the input stream may not be at end of stream and
 * may be in an inconsistent state. It is strongly recommended that the
 * input stream be promptly closed if an I/O error occurs.
 *
 * @param  out the output stream to write to, non-null
 * @return the number of bytes copied
 * @throws IOException if an I/O error occurs when reading or writing
 * @throws NullPointerException  if {@code out} is {@code null}
 *
 * @since 1.9
 */
public long transferTo(OutputStream out) throws IOException { ... }

-Chris.


Looks good to me. The only thing I would change is the @return documentation to 
„the number of bytes transferred“ to be in sync with the method name.


Agreed. Consider it changed.

-Chris.


-Patrick





Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-12-08 Thread Alan Bateman

On 08/12/2014 11:48, Chris Hegarty wrote:
For completeness, here is the finalized spec that we intend to submit 
for approval. Just some minor rewording and grammaticality amendments 
over the previous.


   /**
 * Reads all bytes from this input stream and writes the bytes to 
the given
 * output stream in the order that they are read.  On return, this 
input

 * stream will be at end of stream.
 * p
 * This method may block indefinitely reading from the input stream,
 * or writing to the output stream. The behavior for the case that 
the

 * input and/or output stream is iasynchronously closed/i, or the
 * thread interrupted during the transfer, is highly input and 
output stream

 * specific, and therefore not specified.
 * p
 * If an I/O error occurs reading from the input stream or writing to
 * the output stream, then it may do so after some bytes have been 
read or
 * written. Consequently the input stream may not be at end of 
stream and
 * one, or both, streams may be in an inconsistent state. It is 
strongly
 * recommended that both streams be promptly closed if an I/O 
error occurs.

 *
 * @param  out the output stream, non-null
 * @return the number of bytes transferred
 * @throws IOException if an I/O error occurs when reading or writing
 * @throws NullPointerException  if {@code out} is {@code null}
 *
 * @since 1.9
 */
public long transferTo(OutputStream out) throws IOException { ... }
I'm happy with this updated wording, it's consistent with the wording 
that we already have in Files.copy, and it addresses all the points that 
have come up.


-Alan


Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-12-08 Thread Patrick Reinhart
Hi Chris,

 Am 08.12.2014 um 15:17 schrieb Chris Hegarty chris.hega...@oracle.com:
 
 Again, just for completeness...
 
 Some feedback from Paul Sandoz, to be explicit about the openness of the 
 streams on return. Does not close either stream.
 
 /**
 * Reads all bytes from this input stream and writes the bytes to the given
 * output stream in the order that they are read.  On return, this input
 * stream will be at end of stream. Does not close either stream.
 * p
 * This method may block indefinitely reading from the input stream, or
 * writing to the output stream. The behavior for the case that the input
 * and/or output stream is iasynchronously closed/i, or the thread
 * interrupted during the transfer, is highly input and output stream
 * specific, and therefore not specified.
 * p
 * If an I/O error occurs reading from the input stream or writing to
 * the output stream, then it may do so after some bytes have been read or
 * written. Consequently the input stream may not be at end of stream and
 * one, or both, streams may be in an inconsistent state. It is strongly
 * recommended that both streams be promptly closed if an I/O error occurs.
 *
 * @param  out the output stream, non-null
 * @return the number of bytes transferred
 * @throws IOException if an I/O error occurs when reading or writing
 * @throws NullPointerException  if {@code out} is {@code null}
 *
 * @since 1.9
 */
public long transferTo(OutputStream out) throws IOException
 
 -Chris.

Looks good to me, 

I guess if there are no further change requests on that method we could look at 
the transfer methods for Readable/Appendable. Here we could put a transferTo 
method as a default method on the Readable interface or what do you think?

-Patrick

Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-12-05 Thread Patrick Reinhart
 
 Should those methods also be on the FilterInput- and OutputStream?
 
 I'm not sure I'm following you. j.i.FilterInputStream will get the base 
 version
 of InputStream.copyTo method for free as a child though it doesn't define it
 itself. Every class down the hierarchy starting from the j.i.InputStream will
 get InputStream.copyTo version unless it overrides it.
 To override it, it should of course have some rationale behind it. I believe 
 we
 have found it for at least two widely used subclasses.
 

Sorry,  you are absolutely right, it seems I was somewhere else in my thinking. 
Just ignore that point :-)


 I'm not quit sure about the impact on may already existing customer code 
 that had implemented such a method without declaring a IOException for 
 example. In this case the existing code would may break? (as a comment of 
 Alan Bateman earlier before)
 
 In the case you've mentioned everything should be just fine (technically) as
 overriding method has right to neither throw nor even declare any exceptions
 thrown by the parent method.
 

This point was not completely clear for me. I thought it, but I was not 
completely sure about that fact.

 I said *technically* because the sole fact of overriding doesn't guarantee 
 the 
 child's method has the same semantics as the parent's one. 
 
 It seems to me that it’s not the only possible problematic thing here. We'll 
 see.
 
 -Pavel

I hope there is a change to get that in the JDK9 at the end. I will do as much 
as I can do from my side though.

-Patrick

Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-12-05 Thread Chris Hegarty
The addition of a copyTo method to java.io.InputStream is binary 
compatible [1], but it may, in some cases, be source incompatible. I 
believe the benefits of this approach out weigh the potential source 
incompatibility, but it will be for the spec gods, the CCC, to have 
final say.


Here is what I propose. Let's take just InputStream.copyTo and bring it, 
by itself, to a conclusion. And then revisit each of the additional 
useful/convenience methods on their own merit.


I think we are mostly in agreement on the latest patch Pavel sent out. 
Cut'n'past here, with some grammatical updates.


/**
 * Reads all remaining bytes from this input stream and writes them to
 * the given output stream.
 * p
 * There are no guarantees on the stream's state if an error occurs.
 * Even if this method returns normally you can't rely on previously
 * marked positions, or the contents of any internal buffers. That
 * said, this is a terminal operation. It is strongly recommended
 * that both streams are promptly closed after this method returns:
 * pre{@code
 * try (InputStream is = ...; OutputStream os = ...;) {
 * is.copyTo(os);
 * } catch (IOException e) {
 * ...
 * }
 * }/pre
 * p
 * This method may block indefinitely reading from the input stream,
 * or writing to the output stream. The behavior for the case that the
 * input and/or output stream is iasynchronously closed/i, or the
 * thread interrupted during the copy, is highly input and output stream
 * specific, and therefore not specified.
 *
 * @param  out the output stream to write to, non-null
 * @return the number of bytes copied
 * @throws IOException if an I/O error occurs when reading or writing
 *
 * @since 1.9
 */
public long copyTo(OutputStream out) throws IOException { ... }


-Chris

[1] http://docs.oracle.com/javase/specs/jls/se8/html/jls-13.html


On 04/12/14 23:13, Pavel Rappo wrote:

Patrick,


Should those methods also be on the FilterInput- and OutputStream?


I'm not sure I'm following you. j.i.FilterInputStream will get the base version
of InputStream.copyTo method for free as a child though it doesn't define it
itself. Every class down the hierarchy starting from the j.i.InputStream will
get InputStream.copyTo version unless it overrides it.
To override it, it should of course have some rationale behind it. I believe we
have found it for at least two widely used subclasses.


I'm not quit sure about the impact on may already existing customer code that 
had implemented such a method without declaring a IOException for example. In 
this case the existing code would may break? (as a comment of Alan Bateman 
earlier before)


In the case you've mentioned everything should be just fine (technically) as
overriding method has right to neither throw nor even declare any exceptions
thrown by the parent method.

I said *technically* because the sole fact of overriding doesn't guarantee the
child's method has the same semantics as the parent's one.

It seems to me that it’s not the only possible problematic thing here. We'll 
see.

-Pavel



Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-12-05 Thread Alan Bateman

On 05/12/2014 15:38, Chris Hegarty wrote:
The addition of a copyTo method to java.io.InputStream is binary 
compatible [1], but it may, in some cases, be source incompatible. I 
believe the benefits of this approach out weigh the potential source 
incompatibility, but it will be for the spec gods, the CCC, to have 
final say.


Here is what I propose. Let's take just InputStream.copyTo and bring 
it, by itself, to a conclusion. And then revisit each of the 
additional useful/convenience methods on their own merit.
I think the approach is good. An alternative name to consider is 
transferTo. For the javadoc then you can make it clear that the 
InputStream is at EOF when the method completes. I don't think the 
javadoc needs to say that the OutputStream should be closed promptly 
(think cat a b c  d).


-Alan.


Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-12-05 Thread Chris Hegarty

On 05/12/14 15:59, Alan Bateman wrote:

On 05/12/2014 15:38, Chris Hegarty wrote:

The addition of a copyTo method to java.io.InputStream is binary
compatible [1], but it may, in some cases, be source incompatible. I
believe the benefits of this approach out weigh the potential source
incompatibility, but it will be for the spec gods, the CCC, to have
final say.

Here is what I propose. Let's take just InputStream.copyTo and bring
it, by itself, to a conclusion. And then revisit each of the
additional useful/convenience methods on their own merit.

I think the approach is good. An alternative name to consider is
transferTo. For the javadoc then you can make it clear that the
InputStream is at EOF when the method completes. I don't think the
javadoc needs to say that the OutputStream should be closed promptly
(think cat a b c  d).


Right. Updated spec:

/**
 * Reads all remaining bytes from this input stream and writes them to
 * the given output stream.  On return, this input stream will be 
at end of

 * stream.
 * p
 * This method may block indefinitely reading from the input stream,
 * or writing to the output stream. The behavior for the case that the
 * input and/or output stream is iasynchronously closed/i, or the
 * thread interrupted during the copy, is highly input and output 
stream

 * specific, and therefore not specified.
 * p
 * If an I/O error occurs reading from the input stream or writing to
 * the output stream, then it may do so after some bytes have been 
read or
 * written. Consequently the input stream may not be at end of 
stream and

 * may be in an inconsistent state. It is strongly recommended that the
 * input stream be promptly closed if an I/O error occurs.
 *
 * @param  out the output stream to write to, non-null
 * @return the number of bytes copied
 * @throws IOException if an I/O error occurs when reading or writing
 * @throws NullPointerException  if {@code out} is {@code null}
 *
 * @since 1.9
 */
public long transferTo(OutputStream out) throws IOException { ... }

-Chris.


Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-12-05 Thread Patrick Reinhart
Hi Chris,

 Am 05.12.2014 um 17:36 schrieb Chris Hegarty chris.hega...@oracle.com:
 
 On 05/12/14 15:59, Alan Bateman wrote:
 On 05/12/2014 15:38, Chris Hegarty wrote:
 The addition of a copyTo method to java.io.InputStream is binary
 compatible [1], but it may, in some cases, be source incompatible. I
 believe the benefits of this approach out weigh the potential source
 incompatibility, but it will be for the spec gods, the CCC, to have
 final say.
 
 Here is what I propose. Let's take just InputStream.copyTo and bring
 it, by itself, to a conclusion. And then revisit each of the
 additional useful/convenience methods on their own merit.
 I think the approach is good. An alternative name to consider is
 transferTo. For the javadoc then you can make it clear that the
 InputStream is at EOF when the method completes. I don't think the
 javadoc needs to say that the OutputStream should be closed promptly
 (think cat a b c  d).
 
 Right. Updated spec:
 
/**
 * Reads all remaining bytes from this input stream and writes them to
 * the given output stream.  On return, this input stream will be at end of
 * stream.
 * p
 * This method may block indefinitely reading from the input stream,
 * or writing to the output stream. The behavior for the case that the
 * input and/or output stream is iasynchronously closed/i, or the
 * thread interrupted during the copy, is highly input and output stream
 * specific, and therefore not specified.
 * p
 * If an I/O error occurs reading from the input stream or writing to
 * the output stream, then it may do so after some bytes have been read or
 * written. Consequently the input stream may not be at end of stream and
 * may be in an inconsistent state. It is strongly recommended that the
 * input stream be promptly closed if an I/O error occurs.
 *
 * @param  out the output stream to write to, non-null
 * @return the number of bytes copied
 * @throws IOException if an I/O error occurs when reading or writing
 * @throws NullPointerException  if {@code out} is {@code null}
 *
 * @since 1.9
 */
public long transferTo(OutputStream out) throws IOException { ... }
 
 -Chris.


Looks good to me. The only thing I would change is the @return documentation to 
„the number of bytes transferred“ to be in sync with the method name.

-Patrick



Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-12-05 Thread Chris Hegarty

On 5 Dec 2014, at 17:28, Patrick Reinhart patr...@reini.net wrote:

 Hi Chris,
 
 Am 05.12.2014 um 17:36 schrieb Chris Hegarty chris.hega...@oracle.com:
 
 On 05/12/14 15:59, Alan Bateman wrote:
 On 05/12/2014 15:38, Chris Hegarty wrote:
 The addition of a copyTo method to java.io.InputStream is binary
 compatible [1], but it may, in some cases, be source incompatible. I
 believe the benefits of this approach out weigh the potential source
 incompatibility, but it will be for the spec gods, the CCC, to have
 final say.
 
 Here is what I propose. Let's take just InputStream.copyTo and bring
 it, by itself, to a conclusion. And then revisit each of the
 additional useful/convenience methods on their own merit.
 I think the approach is good. An alternative name to consider is
 transferTo. For the javadoc then you can make it clear that the
 InputStream is at EOF when the method completes. I don't think the
 javadoc needs to say that the OutputStream should be closed promptly
 (think cat a b c  d).
 
 Right. Updated spec:
 
/**
 * Reads all remaining bytes from this input stream and writes them to
 * the given output stream.  On return, this input stream will be at end 
 of
 * stream.
 * p
 * This method may block indefinitely reading from the input stream,
 * or writing to the output stream. The behavior for the case that the
 * input and/or output stream is iasynchronously closed/i, or the
 * thread interrupted during the copy, is highly input and output stream
 * specific, and therefore not specified.
 * p
 * If an I/O error occurs reading from the input stream or writing to
 * the output stream, then it may do so after some bytes have been read or
 * written. Consequently the input stream may not be at end of stream and
 * may be in an inconsistent state. It is strongly recommended that the
 * input stream be promptly closed if an I/O error occurs.
 *
 * @param  out the output stream to write to, non-null
 * @return the number of bytes copied
 * @throws IOException if an I/O error occurs when reading or writing
 * @throws NullPointerException  if {@code out} is {@code null}
 *
 * @since 1.9
 */
public long transferTo(OutputStream out) throws IOException { ... }
 
 -Chris.
 
 Looks good to me. The only thing I would change is the @return documentation 
 to „the number of bytes transferred“ to be in sync with the method name.

Agreed. Consider it changed.

-Chris.

 -Patrick
 



Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-12-04 Thread Pavel Rappo
Patrick, thanks a lot for doing this! I've had a look at these usages,  and I
think it's safe to say that in the JDK it has never been required (yet) to
provide a copy method with custom byte array. So let's skip it for now.

I think more and more about your initial suggestion of introducing a 'copyTo'
method directly into the types:

   InputStream, OutputStream, Readable and Appendable

I believe it will suit us a lot more. If we go this way, we can fully utilize
polymorphic calls. Implementations could then provide their own more efficient
solutions. Have a look at this:

/**
 * Reads all remaining bytes from this input stream and writes them to
 * a specified output stream.
 * p
 * There are no guarantees on streams state in a case error occurs. Even
 * if method returns normally you can't rely on previously marked positions
 * or the contents of any internal buffers.
 * That said, it is a terminal operation. It is strongly recommended that
 * both streams are promptly closed after this method returns:
 * pre{@code
 * try (InputStream is = ...; OutputStream os = ...;) {
 * is.read(os);
 * } catch (IOException e) {
 * ...
 * }
 * }/pre
 * p
 * This method may block indefinitely reading from the input stream
 * (or writing to the output stream). The behavior for the case that the
 * input and output streams is iasynchronously closed/i or the thread
 * interrupted during the copy is highly input and output stream
 * system provider specific and therefore not specified.
 *
 * @param  target  the output stream to write to
 * ({@code target != null})
 * @return the number of bytes copied
 * @throws IOException if an I/O error occurs when reading or writing
 *
 * @since 1.9
 */
public long copyTo(OutputStream target) throws IOException {
Objects.requireNonNull(target, target);
int copied = 0;
byte[] buffer = new byte[8192];
for (int read; (read = this.read(buffer))  -1; copied += read) {
target.write(buffer, 0, read);
}
return copied;
}

This method will be defined in java.io.InputStream. And the following methods
will override 'copyTo' in java.io.ByteArrayInputStream and
java.io.BufferedInputStream respectively:

/**
 * {@inheritDoc}
 */
@Override
public synchronized long copyTo(OutputStream target) throws IOException {
Objects.requireNonNull(target, target);
int avail = count - pos;
target.write(buf, pos, avail);
return avail;
}

/**
 * {@inheritDoc}
 */
@Override
public synchronized long copyTo(OutputStream target) throws IOException {
Objects.requireNonNull(target, target);
long copied = 0;
// 1. Get whatever is left unread in the buffer
if (pos  count) {
int len = count - pos;
target.write(getBufIfOpen(), pos, len);
copied += len;
}
// 2. Get everything else directly from the underlying stream
for (int read; (read = getInIfOpen().read(getBufIfOpen()))  -1;
 copied += read) {
target.write(getBufIfOpen(), 0, read);
}
return copied;
}


1. Please note, that this is not the actual code that will be pushed (if at
   all). It's merely a sketch to illustrate your proposal.
2. The equivalent thing will apply for Readable/Appendable.

-Pavel

 On 2 Dec 2014, at 09:22, Patrick Reinhart patr...@reini.net wrote:
 
 I found around 190 usage references in total of those there are the following 
 28 references that could use my proposed copy feature and 5 of those use 8192 
 bytes sized buffers.



Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-12-04 Thread Patrick Reinhart

Hi Pavel,


Patrick, thanks a lot for doing this! I've had a look at these usages,  and I
think it's safe to say that in the JDK it has never been required (yet) to
provide a copy method with custom byte array. So let's skip it for now.


Welcome, unfortunately I did not manage it to check those on the JDK9 
code base due the fact, that the NetBeans project does not work with the 
modularized codebase jet.



I think more and more about your initial suggestion of introducing a 'copyTo'
method directly into the types:

InputStream, OutputStream, Readable and Appendable


Having a copyTo method on InputStream and Readable was indeed my fist 
idea to have. Also to have a copyFrom method on the OutputStream and 
Appendable was then a natural fit. Looking at those methods it became 
clear to me that in fact we would have a the same code on either 
InputStream and OutputStream or Readable and Appendable.


Of course for OutputStream we could also have something like:

public long copyFrom(InputStream source) throws IOException {
return source.copyTo(this);
}

For the Appendable could it be the same same with a Readable as the 
source in that case.



I believe it will suit us a lot more. If we go this way, we can fully utilize
polymorphic calls. Implementations could then provide their own more efficient
solutions. Have a look at this:

/**
  * Reads all remaining bytes from this input stream and writes them to
  * a specified output stream.
  * p
  * There are no guarantees on streams state in a case error occurs. Even
  * if method returns normally you can't rely on previously marked positions
  * or the contents of any internal buffers.
  * That said, it is a terminal operation. It is strongly recommended that
  * both streams are promptly closed after this method returns:
  * pre{@code
  * try (InputStream is = ...; OutputStream os = ...;) {
  * is.read(os);
  * } catch (IOException e) {
  * ...
  * }
  * }/pre
  * p
  * This method may block indefinitely reading from the input stream
  * (or writing to the output stream). The behavior for the case that the
  * input and output streams is iasynchronously closed/i or the thread
  * interrupted during the copy is highly input and output stream
  * system provider specific and therefore not specified.
  *
  * @param  target  the output stream to write to
  * ({@code target != null})
  * @return the number of bytes copied
  * @throws IOException if an I/O error occurs when reading or writing
  *
  * @since 1.9
  */
public long copyTo(OutputStream target) throws IOException {
 Objects.requireNonNull(target, target);
 int copied = 0;
 byte[] buffer = new byte[8192];
 for (int read; (read = this.read(buffer))  -1; copied += read) {
 target.write(buffer, 0, read);
 }
 return copied;
}

This method will be defined in java.io.InputStream. And the following methods
will override 'copyTo' in java.io.ByteArrayInputStream and
java.io.BufferedInputStream respectively:


Should those methods also be on the FilterInput- and OutputStream?


/**
  * {@inheritDoc}
  */
@Override
public synchronized long copyTo(OutputStream target) throws IOException {
 Objects.requireNonNull(target, target);
 int avail = count - pos;
 target.write(buf, pos, avail);
 return avail;
}

/**
  * {@inheritDoc}
  */
@Override
public synchronized long copyTo(OutputStream target) throws IOException {
 Objects.requireNonNull(target, target);
 long copied = 0;
 // 1. Get whatever is left unread in the buffer
 if (pos  count) {
 int len = count - pos;
 target.write(getBufIfOpen(), pos, len);
 copied += len;
 }
 // 2. Get everything else directly from the underlying stream
 for (int read; (read = getInIfOpen().read(getBufIfOpen()))  -1;
  copied += read) {
 target.write(getBufIfOpen(), 0, read);
 }
 return copied;
}


1. Please note, that this is not the actual code that will be pushed (if at
all). It's merely a sketch to illustrate your proposal.
2. The equivalent thing will apply for Readable/Appendable.

-Pavel


I like that solution almost more then having a separate utility class 
though.


I'm not quit sure about the impact on may already existing customer code 
that had implemented such a method without declaring a IOException for 
example. In this case the existing code would may break? (as a comment 
of Alan Bateman earlier before)


-Patrick


Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-12-04 Thread Pavel Rappo
Patrick,

 Should those methods also be on the FilterInput- and OutputStream?

I'm not sure I'm following you. j.i.FilterInputStream will get the base version
of InputStream.copyTo method for free as a child though it doesn't define it
itself. Every class down the hierarchy starting from the j.i.InputStream will
get InputStream.copyTo version unless it overrides it.
To override it, it should of course have some rationale behind it. I believe we
have found it for at least two widely used subclasses.

 I'm not quit sure about the impact on may already existing customer code that 
 had implemented such a method without declaring a IOException for example. In 
 this case the existing code would may break? (as a comment of Alan Bateman 
 earlier before)

In the case you've mentioned everything should be just fine (technically) as
overriding method has right to neither throw nor even declare any exceptions
thrown by the parent method.

I said *technically* because the sole fact of overriding doesn't guarantee the 
child's method has the same semantics as the parent's one. 

It seems to me that it’s not the only possible problematic thing here. We'll 
see.

-Pavel

Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-12-02 Thread Patrick Reinhart
Finally got the time to search thru the JDK codebase - at the moment JDK8 due 
the lack of a working Netbeans Project for JDK9 (I will try to make that 
working again) 

 What usage would you actually search in the OpenJDK code base?
 
 We're talking about copying with provided buffer, right?
 
 long copy(InputStream source, OutputStream target, byte[] buffer)
   ^
 It would be very helpful to verify that this method is needed extremely rare,
 if at all. In our case it would be an array of very specific
 (other than 1024, 2048, 4096 or 8192) size, i.e. unusually large or small or
 heavily reused one.
 
 To copy from an input stream to an output stream you need to try to read a 
 byte
 from the input stream, at least once. Therefore search for usages of
 these methods will be a good start:
 
 java.io.InputStream#read(byte[])

not referred within the JDK at all

 java.io.InputStream#read(byte[], int, int)

I found around 190 usage references in total of those there are the following 
28 references that could use my proposed copy feature and 5 of those use 8192 
bytes sized buffers.

The short list following shows the path to the resource, line where the byte 
buffer is initialized and the buffer size taken

jdk/src/solaris/classes/sun/print/UnixPrintJob.java 589 / 1024
jdk/src/windows/classes/sun/print/Win32PrintJob.java 444 / 1024
jdk/src/share/classes/sun/security/provider/X509Factory.java 119 / 2048
jdk/src/share/classes/com/sun/media/sound/JavaSoundAudioClip.java 356 / 16384
jdk/src/share/classes/com/sun/media/sound/AudioFileSoundbankReader.java 83 / 
1024
jdk/src/share/classes/javax/swing/text/rtf/AbstractFilter.java 99 / 16384
jdk/src/share/classes/sun/net/NetworkServer.java 120 / 300
jdk/src/share/classes/sun/net/ftp/impl/FtpClient.java 1352 / 15000
jdk/src/share/classes/javax/swing/plaf/basic/BasicLookAndFeel.java 2148 / 1024
jdk/src/share/classes/java/awt/Font.java 934 / 8192
jdk/src/share/classes/sun/security/provider/certpath/X509CertPath.java 259 / 
8192
jdk/src/share/classes/com/sun/media/sound/AiffFileWriter.java 236 / 4096
jdk/src/share/classes/sun/net/www/MimeLauncher.java 118 / 2048
jdk/src/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignatureInput.java
 492 / 4096
jdk/src/share/classes/java/util/jar/JarInputStream.java 109 / 8192
jdk/src/share/classes/sun/tools/jar/Main.java 822 / 8192
jdk/src/share/classes/javax/management/loading/MLet.java 1170 / 4096
jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java 1311 / 8192
jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverDirectHTTP.java
 144 / 4096
jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/Utils.java 52 / 1024
jdk/src/share/classes/java/nio/file/Files.java 2906 / 8192
jdk/src/share/classes/sun/security/tools/keytool/Main.java 2140 / 4096
jdk/src/share/classes/com/sun/media/sound/ModelByteBuffer.java 194 / 1024
jdk/src/share/classes/sun/swing/SwingUtilities2.java 1566 / 1024
jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/JavaUtils.java
 140 / 4096
jdk/src/share/classes/com/sun/media/sound/SoftMixingClip.java 333 / multiple of 
512
jdk/src/share/classes/com/sun/media/sound/StandardMidiFileWriter.java 141 / 
16384
jdk/src/share/classes/com/sun/media/sound/WaveFileWriter.java 236 / 4096




Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-28 Thread Pavel Rappo
I'm happy with any tool which is capable of usages search. Configured IDE is 
a good choice.

-Pavel

 On 27 Nov 2014, at 22:59, Patrick Reinhart patr...@reini.net wrote:
 
 I have to say, that I normally use my IDE to search for references. 
 
 What technique do you use to search for such patterns?



Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-28 Thread Bernd Eckenfels
Am Fri, 28 Nov 2014 12:09:11 +
schrieb Pavel Rappo pavel.ra...@oracle.com:

 I'm happy with any tool which is capable of usages search.
 Configured IDE is a good choice.

What usage would you actually search in the OpenJDK code base?

I think it is not very representative to search for usage in the JDK
code base even if it would be possible. However you can use for commons
IO or Guava. Both have those helpers. (Which initself might be
justification enough - the question is only pro or con including it in
JCL :) 

Gruss
Bernd


Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-28 Thread Patrick Reinhart


 Am 28.11.2014 um 20:15 schrieb Bernd Eckenfels e...@zusammenkunft.net:
 
 Am Fri, 28 Nov 2014 12:09:11 +
 schrieb Pavel Rappo pavel.ra...@oracle.com:
 
 I'm happy with any tool which is capable of usages search.
 Configured IDE is a good choice.
 
 What usage would you actually search in the OpenJDK code base?
 
 I think it is not very representative to search for usage in the JDK
 code base even if it would be possible. However you can use for commons
 IO or Guava. Both have those helpers. (Which initself might be
 justification enough - the question is only pro or con including it in
 JCL :) 
 
 Gruss
 Bernd

When looking at the guava library there seems to be no need for copy method 
that is able to pass in a separate byte array or CharBuffer. It would make more 
sense to have also a copy channels method on the existing 
java.nio.channels.Channels class instead.

In all the projects I have worked on, there was always the point of having to 
either implement my own copy methods or use a certain library (for mostly only 
using the copy methods). Having said that, it seems to be a natural fit.  Also 
when looking on the java.nio.files.Files class for copying with source or 
target Path’s it makes even more sense.

-Patrick

Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-28 Thread Pavel Rappo

 What usage would you actually search in the OpenJDK code base?

We're talking about copying with provided buffer, right?

long copy(InputStream source, OutputStream target, byte[] buffer)
   ^
It would be very helpful to verify that this method is needed extremely rare,
if at all. In our case it would be an array of very specific
(other than 1024, 2048, 4096 or 8192) size, i.e. unusually large or small or
heavily reused one.

To copy from an input stream to an output stream you need to try to read a byte
from the input stream, at least once. Therefore search for usages of
these methods will be a good start:

java.io.InputStream#read(byte[])
java.io.InputStream#read(byte[], int, int)

-Pavel



Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-27 Thread Patrick Reinhart

Hi Paul,

Attached a patch containing my complete proposed code including tests.

Patrick



 Am 24.11.2014 um 18:03 schrieb Patrick Reinhart patr...@reini.net:
 
 Well I will then suggest using IOUtils with two simple methods:
 
 public static long copy(InputStream source, OutputStream target)
 
 public static long copy(Readable source, Appendable target)
 
 
 
 To speed things along for now i recommend creating a new class say IOUtils 
 or preferably ByteStreams. 
 
 Hmm, in the case of Reader/Writer ByteStreams seams to be a bit confusing 
 for me, should then the reader copy stuff go to also a separate class like 
 „CharStreams“. Locally I created an implementation named „IOUtils“ 
 containing a copy method for InputStream to OutputStream.
 
 
 Pick the one you prefer so we don't rat hole down the naming abyss :-)
 
 Pavel, your point about the overload with j.u.stream.Stream is a reasonable 
 one (I am not too concerned by it myself). I hope one day in the future we 
 can have Streamint :-)
 
 Paul.
 
 Patrick



Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-27 Thread Patrick Reinhart
Hi Paul,

Seems not to work. See inline patch…

Patrick


 Hi Paul,
 
 Attached a patch containing my complete proposed code including tests.
 
 Patrick

--- /dev/null   2014-11-24 08:00:19.282694686 +0100
+++ new/src/java.base/share/classes/java/io/IOUtil.java 2014-11-27 
10:33:39.955791833 +0100
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the Classpath exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.io;
+
+import java.nio.CharBuffer;
+
+/**
+ * Utility methods for copying data between a {@link InputStream} and
+ * {@link OutputStream} or between a {@link Readable} and a {@link Appendable}.
+ */
+public final class IOUtil {
+
+// buffer size used for reading and writing
+private static final int BUFFER_SIZE = 8192;
+
+private IOUtil() {
+throw new Error(no instances);
+}
+
+/**
+ * Reads all bytes from an input stream and writes them to an output 
stream.
+ *
+ * @param source the input stream to read from
+ * @param target the output stream to write to
+ *
+ * @return the number of bytes successfully read and written
+ *
+ * @throws IOException if an I/O error occurs when reading or writing
+ */
+public static long copy(InputStream source, OutputStream target)
+throws IOException {
+long totalRead = 0L;
+byte[] buffer = new byte[BUFFER_SIZE];
+int read;
+while ((read = source.read(buffer))  -1) {
+target.write(buffer, 0, read);
+totalRead += read;
+}
+return totalRead;
+}
+
+/**
+ * Reads all characters from an readable and writes them to an appendable.
+ *
+ * @param source the readable to read from
+ * @param target the appendable to write to
+ *
+ * @return the number of characters successfully read and written
+ *
+ * @throws IOException if an I/O error occurs when reading or writing
+ */
+public static long copy(Readable source, Appendable target) throws 
IOException {
+long totalRead = 0L;
+CharBuffer buffer = CharBuffer.allocate(BUFFER_SIZE);
+int read;
+while ((read = source.read(buffer))  -1) {
+   buffer.flip();
+target.append(buffer, 0, read);
+totalRead += read;
+}
+return totalRead;
+}
+}
--- /dev/null   2014-11-24 08:00:19.282694686 +0100
+++ new/test/java/io/IOUtil/CopyInputStreamOutputStream.java2014-11-27 
10:33:40.352791912 +0100
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOUtil;
+import java.util.Arrays;
+
+/* @test
+   @summary Test copy a InputStream to a OutputStream reporting the amount 
+of bytes copied in total.
+ */

Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-27 Thread Pavel Rappo
I've created an initial webrev for this change: 
http://cr.openjdk.java.net/~prappo/ioutil/webrev.00/
Welcome to discussion.

P.S. The only thing I changed was the license header.

-Pavel

 On 27 Nov 2014, at 09:48, Patrick Reinhart patr...@reini.net wrote:
 
 Hi Paul,
 
 Seems not to work. See inline patch…



Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-27 Thread Patrick Reinhart
Hi Pavel,

Thanks very much for your help. I’ve try my best to get author state ;-)

Patrick

 Am 27.11.2014 um 12:58 schrieb Pavel Rappo pavel.ra...@oracle.com:
 
 I've created an initial webrev for this change: 
 http://cr.openjdk.java.net/~prappo/ioutil/webrev.00/
 Welcome to discussion.
 
 P.S. The only thing I changed was the license header.
 
 -Pavel
 
 On 27 Nov 2014, at 09:48, Patrick Reinhart patr...@reini.net wrote:
 
 Hi Paul,
 
 Seems not to work. See inline patch…
 



Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-27 Thread Pavel Rappo
At the bare minimum I would use runtime null/range checks and give a little bit 
more freedom for those who want to control buffer (or probably reuse already 
existing one): http://cr.openjdk.java.net/~prappo/ioutil/webrev.01/

I would also add some clarifications in the javadoc.

-Pavel



Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-27 Thread Patrick Reinhart
Added null checks also to Readable/Appendable copy methods

Patrick

 Am 27.11.2014 um 13:26 schrieb Pavel Rappo pavel.ra...@oracle.com:
 
 At the bare minimum I would use runtime null/range checks and give a little 
 bit more freedom for those who want to control buffer (or probably reuse 
 already existing one): http://cr.openjdk.java.net/~prappo/ioutil/webrev.01/
 
 I would also add some clarifications in the javadoc.
 
 -Pavel
 


diff -r 194458fe7339 src/java.base/share/classes/java/io/IOUtil.java
--- a/src/java.base/share/classes/java/io/IOUtil.java   Thu Nov 27 13:50:36 
2014 +0100
+++ b/src/java.base/share/classes/java/io/IOUtil.java   Thu Nov 27 14:00:07 
2014 +0100
@@ -71,7 +71,6 @@
  */
 public static long copy(InputStream source, OutputStream target,
 byte[] buffer) throws IOException {
-
 Objects.requireNonNull(source, source);
 Objects.requireNonNull(target, target);
 Objects.requireNonNull(buffer, buffer);
@@ -100,15 +99,15 @@
  * @throws IOException if an I/O error occurs when reading or writing
  */
 public static long copy(Readable source, Appendable target) throws 
IOException {
-long totalRead = 0L;
+Objects.requireNonNull(source, source);
+Objects.requireNonNull(target, target);
+long copied = 0L;
 CharBuffer buffer = CharBuffer.allocate(BUFFER_SIZE);
-int read;
-while ((read = source.read(buffer))  -1) {
+for (int read; (read = source.read(buffer))  -1; copied += read) {
buffer.flip();
 target.append(buffer, 0, read);
-totalRead += read;
 }
-return totalRead;
+return copied;
 }
 }
 



Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-27 Thread Pavel Rappo
Patrick, as soon as I get feedback from Alan and Paul I'll merge these changes 
into the current version.

1. I wonder if it makes sense to provide an additional method where client 
specifies CharBuffer to be used?
Moreover if the first argument is CharSequence then we don't even need a buffer:

/**
 * Reads all characters from a readable and appends them to an appendable.
 *
 * @param source   the readable to read from ({@code source != null})
 * @param target   the appendable to append to ({@code target != null})
 *
 * @return the number of characters copied
 *
 * @throws IOException if an I/O error occurs when reading or appending
 */
public static long copy(Readable source, Appendable target)
throws IOException {
Objects.requireNonNull(source, source);
Objects.requireNonNull(target, target);

if (source instanceof CharSequence)
return copy1((CharSequence) source, target);

return copy0(source, target, CharBuffer.allocate(BUFFER_SIZE));
}

/**
 * Reads all characters from a readable and appends them to an appendable.
 *
 * @param source   the readable to read from ({@code source != null})
 * @param target   the appendable to append to ({@code target != null})
 * @param buffer   the intermediate buffer to use
 * ({@code buffer != null  buffer.hasRemaining()
 *  !buffer.isReadOnly()})
 * @return the number of characters copied
 * @throws IOException if an I/O error occurs when reading or appending
 */
public static long copy(Readable source, Appendable target,
CharBuffer buffer) throws IOException {
Objects.requireNonNull(source, source);
Objects.requireNonNull(target, target);
Objects.requireNonNull(buffer, buffer);
if (!buffer.hasRemaining())
throw new IllegalArgumentException(Insufficient buffer size);
if (buffer.isReadOnly())
throw new IllegalArgumentException(buffer is read only);
return copy0(source, target, buffer);
}

private static long copy1(CharSequence source, Appendable target)
throws IOException {
long copied = source.length();
target.append(source);
return copied;
}

private static long copy0(Readable source, Appendable target,
  CharBuffer buffer) throws IOException {

2. I think guts of the copy method could be changed to something like this:

long copied = 0L;
+   int oldLim = buffer.limit();

for (int read; (read = source.read(buffer))  -1; copied += read) {
buffer.flip();
target.append(buffer, 0, read);
+   buffer.limit(oldLim);
}
return copied;

Otherwise on each iteration you're potentially shrinking available buffer 
storage based on
amount of data read into it (if I'm not mistaken). So each time you should 
restore the limit.

3. We should think of revisiting and including the only method from 
sun.misc.IOUtils. Removing
the class and reparenting its dependencies. 



-Pavel

 diff -r 194458fe7339 src/java.base/share/classes/java/io/IOUtil.java
 --- a/src/java.base/share/classes/java/io/IOUtil.java Thu Nov 27 13:50:36 
 2014 +0100
 +++ b/src/java.base/share/classes/java/io/IOUtil.java Thu Nov 27 16:08:09 
 2014 +0100
 @@ -47,10 +47,28 @@
 /**
  * Reads all bytes from an input stream and writes them to an output 
 stream.
  *
 - * @param source   the input stream to read from
 - * @param target   the output stream to write to
 - * @return the number of bytes successfully copied
 - * @throws IOException if an I/O error occurs when reading or writing
 + * p  If an I/O error occurs reading from the input stream or writing 
 to
 + * the output stream, then it may do so after the some bytes have been 
 read 
 + * or written. Consequently the input stream may not be at end of stream 
 and 
 + * may be in an inconsistent state. It is strongly recommended that the 
 input
 + * and output stream be promptly closed if an I/O error occurs.
 + *
 + * p This method may block indefinitely reading from the input stream 
 (or
 + * writing to the output stream). The behavior for the case that the 
 input 
 + * and output stream is iasynchronously closed/i or the thread 
 interrupted
 + * during the copy is highly input and output stream system provider 
 specific 
 + * and therefore not specified.
 + *
 + * @param   source
 + *  the input stream to read from
 + * @param   target
 + *  the output stream to write to
 + *
 + * @return  the number of bytes successfully copied
 + * @throws  IOException
 + *  if an I/O error occurs when reading or writing. In 
 particular,
 + *  an codeIOException/code may be thrown if the output 
 stream 
 + *  has been closed.
  */
 public static long copy(InputStream source, OutputStream target)
 throws 

Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-27 Thread Patrick Reinhart
 Patrick, as soon as I get feedback from Alan and Paul I'll merge these 
 changes into the current version.
 
 1. I wonder if it makes sense to provide an additional method where client 
 specifies CharBuffer to be used?
 Moreover if the first argument is CharSequence then we don't even need a 
 buffer:
 
 /**
 * Reads all characters from a readable and appends them to an appendable.
 *
 * @param source   the readable to read from ({@code source != null})
 * @param target   the appendable to append to ({@code target != null})
 *
 * @return the number of characters copied
 *
 * @throws IOException if an I/O error occurs when reading or appending
 */
 public static long copy(Readable source, Appendable target)
throws IOException {
Objects.requireNonNull(source, source);
Objects.requireNonNull(target, target);
 
if (source instanceof CharSequence)
return copy1((CharSequence) source, target);
 
return copy0(source, target, CharBuffer.allocate(BUFFER_SIZE));
 }
 
 /**
 * Reads all characters from a readable and appends them to an appendable.
 *
 * @param source   the readable to read from ({@code source != null})
 * @param target   the appendable to append to ({@code target != null})
 * @param buffer   the intermediate buffer to use
 * ({@code buffer != null  buffer.hasRemaining()
 *  !buffer.isReadOnly()})
 * @return the number of characters copied
 * @throws IOException if an I/O error occurs when reading or appending
 */
 public static long copy(Readable source, Appendable target,
CharBuffer buffer) throws IOException {
Objects.requireNonNull(source, source);
Objects.requireNonNull(target, target);
Objects.requireNonNull(buffer, buffer);
if (!buffer.hasRemaining())
throw new IllegalArgumentException(Insufficient buffer size);
if (buffer.isReadOnly())
throw new IllegalArgumentException(buffer is read only);
return copy0(source, target, buffer);
 }
 
 private static long copy1(CharSequence source, Appendable target)
throws IOException {
long copied = source.length();
target.append(source);
return copied;
 }
 
 private static long copy0(Readable source, Appendable target,
  CharBuffer buffer) throws IOException {
 

Seems reasonable to me. Will you add those changes additionally to mine then? 


 2. I think guts of the copy method could be changed to something like this:
 
long copied = 0L;
 +   int oldLim = buffer.limit();
 
for (int read; (read = source.read(buffer))  -1; copied += read) {
   buffer.flip();
target.append(buffer, 0, read);
 +   buffer.limit(oldLim);
}
return copied;
 
 Otherwise on each iteration you're potentially shrinking available buffer 
 storage based on
 amount of data read into it (if I'm not mistaken). So each time you should 
 restore the limit.

There I’m not that experienced either. I’m shamed about it, but never used 
CharBuffer by myself so far… (my implementation could therefore be not 
completely correct)


 3. We should think of revisiting and including the only method from 
 sun.misc.IOUtils. Removing
 the class and reparenting its dependencies. 

That would be a followup task - on the way to authorship ;-)

-Patrick





Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-27 Thread Pavel Rappo
Yes I will. If I don't see any objections.
 
-Pavel

 On 27 Nov 2014, at 16:10, Patrick Reinhart patr...@reini.net wrote:
 
 Will you add those changes additionally to mine then? 



Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-27 Thread Alan Bateman

On 27/11/2014 15:56, Pavel Rappo wrote:

Patrick, as soon as I get feedback from Alan and Paul I'll merge these changes 
into the current version.

1. I wonder if it makes sense to provide an additional method where client 
specifies CharBuffer to be used?
Moreover if the first argument is CharSequence then we don't even need a buffer:

I would suggest starting out with the simple copy(source, target) and 
only add additional variants if there is strong need. In this case, is a 
variant that allows the intermediate buffer to be specified be something 
that would be widely used?


-Alan


Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-27 Thread Patrick Reinhart

 Am 27.11.2014 um 17:57 schrieb Alan Bateman alan.bate...@oracle.com:
 
 On 27/11/2014 15:56, Pavel Rappo wrote:
 Patrick, as soon as I get feedback from Alan and Paul I'll merge these 
 changes into the current version.
 
 1. I wonder if it makes sense to provide an additional method where client 
 specifies CharBuffer to be used?
 Moreover if the first argument is CharSequence then we don't even need a 
 buffer:
 
 I would suggest starting out with the simple copy(source, target) and only 
 add additional variants if there is strong need. In this case, is a variant 
 that allows the intermediate buffer to be specified be something that would 
 be widely used?
 
 -Alan

In our codebase here we have variants of different buffer sizes, mostly there 
are some with smaller sizes than the default I took from the Files class. To 
have the copy function within the JDK instead using a separate library or have 
this code written over and over again is much more important to me.

-Patrick

Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-27 Thread Alan Bateman

On 27/11/2014 17:40, Patrick Reinhart wrote:

:
In our codebase here we have variants of different buffer sizes, mostly there 
are some with smaller sizes than the default I took from the Files class. To 
have the copy function within the JDK instead using a separate library or have 
this code written over and over again is much more important to me.

I think a variant that has a size as an argument is worth considering, 
we've all done that. That said, Pavel's suggestion seem to be a 
intermediate buffer the hint as to the chunk size.


-Alan


Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-27 Thread Pavel Rappo
Patrick, Alan is right in the sense that we have to estimate usefulness of each 
method wisely. Unfortunately your codebase (or anyone else's) might have some 
very specific biases and thus might not be a good sample to base conclusions 
upon.

We need some more data to justify this proposal. The good start could be the 
jdk itself -- to see if those copy-with-my-buffer methods could be useful here.
 
-Pavel

 On 27 Nov 2014, at 17:40, Patrick Reinhart patr...@reini.net wrote:
 
 
 Am 27.11.2014 um 17:57 schrieb Alan Bateman alan.bate...@oracle.com:
 
 On 27/11/2014 15:56, Pavel Rappo wrote:
 Patrick, as soon as I get feedback from Alan and Paul I'll merge these 
 changes into the current version.
 
 1. I wonder if it makes sense to provide an additional method where client 
 specifies CharBuffer to be used?
 Moreover if the first argument is CharSequence then we don't even need a 
 buffer:
 
 I would suggest starting out with the simple copy(source, target) and only 
 add additional variants if there is strong need. In this case, is a variant 
 that allows the intermediate buffer to be specified be something that would 
 be widely used?
 
 -Alan
 
 In our codebase here we have variants of different buffer sizes, mostly there 
 are some with smaller sizes than the default I took from the Files class. To 
 have the copy function within the JDK instead using a separate library or 
 have this code written over and over again is much more important to me.
 
 -Patrick



Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-27 Thread Patrick Reinhart

 Patrick, Alan is right in the sense that we have to estimate usefulness of 
 each method wisely. Unfortunately your codebase (or anyone else’s) might have 
 some very specific biases and thus might not be a good sample to base 
 conclusions upon.

Aggreed.

 We need some more data to justify this proposal. The good start could be the 
 jdk itself -- to see if those copy-with-my-buffer methods could be useful 
 here.
 
 -Pavel


I have to say, that I normally use my IDE to search for references. 

What technique do you use to search for such patterns?

-Patrick

Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-24 Thread Paul Sandoz
Hi Patrick,

To speed things along for now i recommend creating a new class say IOUtils or 
preferably ByteStreams. 

You should keep things simple for an initial iteration and just add one static 
method :-) which is essentially a refined copy of the private method that Pavel 
pointed out. Then write some tests for that method [1]. Then consider any nio 
related classes for an equivalent copy method. Some other candidates to 
consider are on Guava's ByteStreams class:

  
http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/io/ByteStreams.html

It's very easy to get carried away and over-engineer such utility methods 
thinking they need to be all things to all people so we need to consider them 
carefully and i think the ones you included with size and reporting are not 
required. Simply just one static method copying input to output will go a long 
way (i have lost count of how many times i have reimplemented that!).

Hth,
Paul.

[1] You can download jtreg from here:

  https://adopt-openjdk.ci.cloudbees.com/view/OpenJDK/job/jtreg/

for executing JDK tests. Depending on how you want to write your tests you can 
also make 'em run standalone too, but sometimes it is easier convenient to use 
testng and execute via jtreg.


On Nov 21, 2014, at 3:12 PM, Patrick Reinhart patr...@reini.net wrote:

 
 Am 21.11.2014 um 09:36 schrieb Alan Bateman alan.bate...@oracle.com:
 
 On 21/11/2014 03:05, Stuart Marks wrote:
 
 Thanks to Pavel for pointing out the existing copy operations in the nio 
 Files class. I think there's a case for the InputStream = OutputStream 
 copy method to be placed there too, although I admit it is somewhat unusual 
 in that it doesn't actually have anything to do with files.
 
 At my first encounter with the nio.Files class some years ago I saw the 
 following copying methods:
 
   copy(istream, targetfile)
   copy(sourcefile, ostream)
   copy(sourcefile, targetfile)
 
 and I immediately thought, Where is copy(istream, ostream)? So to me at 
 least, it makes more sense to be in the Files class than in some newly 
 created IOUtils class. (I'd like to hear further from Alan on this.)
 
 As Pavel pointed out, the logic is also already there in the Files class. 
 Probably the way to proceed would be to rename the existing (private) 
 method to be something like copyInternal() and then create a new, public 
 copy(istream, ostream) method that does argument checking before calling 
 copyInternal().
 
 The Files class works on files, it's not the right place for a general 
 purpose copy(InputStream, OutputStream).
 
 That was the reason in my proposal to not put those methods on the Files 
 class. I also would not try to find such methods there. Personally I tried to 
 look for such method on „Streams“ ;-)
 
 When we prototyped a copy(InputStream, OutputStream) and many other I/O 
 methods a few years ago then the intention was to put it java.io. One option 
 on the table was a Collections-like utility class with static methods. 
 Another option was to add methods to InputStream, Reader, etc. A concern 
 with the latter was whether the new methods would cause problems for 
 existing InputStream/etc. implementations, similar to concerns about adding 
 default methods to the collection types in 8. I think that discussion needs 
 to happen again and having a few prototypes to get experience with the 
 various approaches would be good too.
 
 -Alan
 
 It would be good to have such methods in the next release and I would love to 
 help here.
 
 Patrick



Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-24 Thread Pavel Rappo
Paul, I wouldn't name it 'ByteStreams' because of the possible subjective 
associations (and confusion) with java.util.stream.IntStream, 
java.util.stream.LongStream, etc.
IOStreams?

-Pavel

 On 24 Nov 2014, at 14:32, Paul Sandoz paul.san...@oracle.com wrote:
 
 i recommend creating a new class say IOUtils or preferably ByteStreams.



Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-24 Thread Patrick Reinhart
Hi Paul,

 Am 24.11.2014 um 15:32 schrieb Paul Sandoz paul.san...@oracle.com:
 
 Hi Patrick,
 
 To speed things along for now i recommend creating a new class say IOUtils or 
 preferably ByteStreams. 

Hmm, in the case of Reader/Writer ByteStreams seams to be a bit confusing for 
me, should then the reader copy stuff go to also a separate class like 
„CharStreams“. Locally I created an implementation named „IOUtils“ containing a 
copy method for InputStream to OutputStream.

 You should keep things simple for an initial iteration and just add one 
 static method :-) which is essentially a refined copy of the private method 
 that Pavel pointed out. Then write some tests for that method [1]. Then 
 consider any nio related classes for an equivalent copy method. Some other 
 candidates to consider are on Guava's ByteStreams class:
 
  
 http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/io/ByteStreams.html

I will also take a look at this

 It's very easy to get carried away and over-engineer such utility methods 
 thinking they need to be all things to all people so we need to consider them 
 carefully and i think the ones you included with size and reporting are not 
 required. Simply just one static method copying input to output will go a 
 long way (i have lost count of how many times i have reimplemented that!).

For now a single copy(from, to) for Input-/OutputStream and Readable/Appendable 
would be perfect for now.

 Hth,
 Paul.
 
 [1] You can download jtreg from here:
 
  https://adopt-openjdk.ci.cloudbees.com/view/OpenJDK/job/jtreg/
 
 for executing JDK tests. Depending on how you want to write your tests you 
 can also make ‚em run standalone too, but sometimes it is easier convenient 
 to use testng and execute via jtreg.

The environment I will update in the next.

Patrick

Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-24 Thread Paul Sandoz

On Nov 24, 2014, at 5:34 PM, Patrick Reinhart patr...@reini.net wrote:

 Hi Paul,
 
 Am 24.11.2014 um 15:32 schrieb Paul Sandoz paul.san...@oracle.com:
 
 Hi Patrick,
 
 To speed things along for now i recommend creating a new class say IOUtils 
 or preferably ByteStreams. 
 
 Hmm, in the case of Reader/Writer ByteStreams seams to be a bit confusing for 
 me, should then the reader copy stuff go to also a separate class like 
 „CharStreams“. Locally I created an implementation named „IOUtils“ containing 
 a copy method for InputStream to OutputStream.
 

Pick the one you prefer so we don't rat hole down the naming abyss :-)

Pavel, your point about the overload with j.u.stream.Stream is a reasonable one 
(I am not too concerned by it myself). I hope one day in the future we can have 
Streamint :-)

Paul.


Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-24 Thread Patrick Reinhart
Well I will then suggest using IOUtils with two simple methods:

public static long copy(InputStream source, OutputStream target)

public static long copy(Readable source, Appendable target)


 
 To speed things along for now i recommend creating a new class say IOUtils 
 or preferably ByteStreams. 
 
 Hmm, in the case of Reader/Writer ByteStreams seams to be a bit confusing 
 for me, should then the reader copy stuff go to also a separate class like 
 „CharStreams“. Locally I created an implementation named „IOUtils“ 
 containing a copy method for InputStream to OutputStream.
 
 
 Pick the one you prefer so we don't rat hole down the naming abyss :-)
 
 Pavel, your point about the overload with j.u.stream.Stream is a reasonable 
 one (I am not too concerned by it myself). I hope one day in the future we 
 can have Streamint :-)
 
 Paul.

Patrick

Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-21 Thread Alan Bateman

On 21/11/2014 03:05, Stuart Marks wrote:


Thanks to Pavel for pointing out the existing copy operations in the 
nio Files class. I think there's a case for the InputStream = 
OutputStream copy method to be placed there too, although I admit it 
is somewhat unusual in that it doesn't actually have anything to do 
with files.


At my first encounter with the nio.Files class some years ago I saw 
the following copying methods:


copy(istream, targetfile)
copy(sourcefile, ostream)
copy(sourcefile, targetfile)

and I immediately thought, Where is copy(istream, ostream)? So to me 
at least, it makes more sense to be in the Files class than in some 
newly created IOUtils class. (I'd like to hear further from Alan on 
this.)


As Pavel pointed out, the logic is also already there in the Files 
class. Probably the way to proceed would be to rename the existing 
(private) method to be something like copyInternal() and then create a 
new, public copy(istream, ostream) method that does argument checking 
before calling copyInternal().


The Files class works on files, it's not the right place for a general 
purpose copy(InputStream, OutputStream).


When we prototyped a copy(InputStream, OutputStream) and many other I/O 
methods a few years ago then the intention was to put it java.io. One 
option on the table was a Collections-like utility class with static 
methods. Another option was to add methods to InputStream, Reader, etc. 
A concern with the latter was whether the new methods would cause 
problems for existing InputStream/etc. implementations, similar to 
concerns about adding default methods to the collection types in 8. I 
think that discussion needs to happen again and having a few prototypes 
to get experience with the various approaches would be good too.


-Alan


Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-21 Thread Patrick Reinhart

 Am 21.11.2014 um 09:36 schrieb Alan Bateman alan.bate...@oracle.com:
 
 On 21/11/2014 03:05, Stuart Marks wrote:
 
 Thanks to Pavel for pointing out the existing copy operations in the nio 
 Files class. I think there's a case for the InputStream = OutputStream copy 
 method to be placed there too, although I admit it is somewhat unusual in 
 that it doesn't actually have anything to do with files.
 
 At my first encounter with the nio.Files class some years ago I saw the 
 following copying methods:
 
copy(istream, targetfile)
copy(sourcefile, ostream)
copy(sourcefile, targetfile)
 
 and I immediately thought, Where is copy(istream, ostream)? So to me at 
 least, it makes more sense to be in the Files class than in some newly 
 created IOUtils class. (I'd like to hear further from Alan on this.)
 
 As Pavel pointed out, the logic is also already there in the Files class. 
 Probably the way to proceed would be to rename the existing (private) method 
 to be something like copyInternal() and then create a new, public 
 copy(istream, ostream) method that does argument checking before calling 
 copyInternal().
 
 The Files class works on files, it's not the right place for a general 
 purpose copy(InputStream, OutputStream).

That was the reason in my proposal to not put those methods on the Files class. 
I also would not try to find such methods there. Personally I tried to look for 
such method on „Streams“ ;-)

 When we prototyped a copy(InputStream, OutputStream) and many other I/O 
 methods a few years ago then the intention was to put it java.io. One option 
 on the table was a Collections-like utility class with static methods. 
 Another option was to add methods to InputStream, Reader, etc. A concern with 
 the latter was whether the new methods would cause problems for existing 
 InputStream/etc. implementations, similar to concerns about adding default 
 methods to the collection types in 8. I think that discussion needs to happen 
 again and having a few prototypes to get experience with the various 
 approaches would be good too.
 
 -Alan

It would be good to have such methods in the next release and I would love to 
help here.

Patrick

Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-20 Thread Pavel Rappo
Hi Patrick,

There is at least one method in the JDK with similar characteristics: 
java.nio.file.Files#copy(java.io.InputStream, java.io.OutputStream)
But, (1) it has a private access (2) even if we made it public I doubt 
java.nio.file.Files would be a good place for it

P.S. The thing that confuses me though, is the progress consumer. I believe 
this feature is rarely needed (at least in a way you described it).
If you want to do something like this, you should probably go asynchronous with 
full blown solution like what they have in javax.swing.SwingWorker.
 
-Pavel

 On 13 Nov 2014, at 19:31, Patrick Reinhart patr...@reini.net wrote:
 
 Hi there,
 
 In the followup of a BOF with Stephen Colebourne with his ideas of small 
 library changes that may could get in JDK9. As of the fact that in the 
 codebase of my company there are several locations where we copy from/to IO 
 stream over and over again using either external libraries or do it by 
 ourselves,  I suggested to have some support for easy coping data between 
 Input-/OutputStream or Reader/Writer without having to use to external 
 libraries.
 
 My suggestion would look something like this:
 
 try (InputStream in = … ; OutputStream out = …) {
  in.copyTo(out);
 }
 
 Or from the other end:
 
 try (InputStream in = … ; OutputStream out = …) {
  out.copyFrom(in);
 }
 
 The same for character based streams:
 
 try (Reader in = …; Writer out = …) {
  in.copyTo(out);
 }
 
 or
 
 try (Reader in = …; Writer out = …) {
  out.copyFrom(in);
 }
 
 
 What do you think about this idea? I could imagine, that we could also pass a 
 IntConsumer / LongConsumer in, that will be called with each amount of 
 successfully copied amount of bytes/chars in case we need a total amount of 
 data or displaying the progress of copy externally.
 
 I’m looking forward to your opinions upon this proposal.
 
 Cheers
 
 Patrick



Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-20 Thread Patrick Reinhart
Hi Pavel,
 Am 20.11.2014 um 10:22 schrieb Pavel Rappo pavel.ra...@oracle.com:
 
 There is at least one method in the JDK with similar characteristics: 
 java.nio.file.Files#copy(java.io.InputStream, java.io.OutputStream)
 But, (1) it has a private access (2) even if we made it public I doubt 
 java.nio.file.Files would be a good place for it
 

I would suggest to introduce a separate IOUtil class holding such utility 
methods. Additionally to copyTo() and copyFrom() method could be added later 
for more intuitive usage. Also the copy method within the Files method could be 
replaced with a static reference to the IOUtil class.


 P.S. The thing that confuses me though, is the progress consumer. I believe 
 this feature is rarely needed (at least in a way you described it).
 If you want to do something like this, you should probably go asynchronous 
 with full blown solution like what they have in javax.swing.SwingWorker.
 
 -Pavel

The method having a IntConsumer I have already discussed with some other 
colleagues and they suggested to better use a IntPredicate in order to have the 
possibility to interrupt the copy process, without having to interrupt any 
threads. Additionally there is still the possibility to use such a Predicate 
for counting the total or using the information for other possibilities.

Here’s implementation example for Input-/OutputStream (similar code would apply 
for Reader/Writer):

/**
 * Reads all bytes from an input stream and writes them to an output stream.
 *
 * @param source the input stream to read from
 * @param target the path to the file
 *
 * @return the number of bytes read and successfully written
 *
 * @throws IOException if an I/O error occurs when reading or writing
 */
public static long copy(InputStream source, OutputStream target)
throws IOException {
LongAdder totalread = new LongAdder();
copy(source, target, nread - {
totalread.add(nread);
return true;
});
return totalread.sum();
}

/**
 * Reads all bytes from an input stream and writes them to an output stream.
 * While doing so, the given predicate is called with the amount of bytes
 * being read, to decide whenever they should be written to the output
 * stream. If the predicate returns codefalse/code the copy operation is
 * stopped and no more data is written to the output stream.
 *
 * @param source the input stream to read from
 * @param target the path to the file
 * @param predicate the predicate tests if the copy operation should proceed
 *
 * @throws IOException if an I/O error occurs when reading or writing
 */
public static void copy(InputStream source, OutputStream target,
IntPredicate predicate) throws IOException {
byte[] buf = new byte[BUFFER_SIZE];
int n;
while ((n = source.read(buf))  0  predicate.test(n)) {
target.write(buf, 0, n);
}
}

Cheers

Patrick

Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-20 Thread Stuart Marks

Hi Patrick,

Good to meet you in Antwerp!

On 11/20/14 10:30 AM, Patrick Reinhart wrote:

Am 20.11.2014 um 10:22 schrieb Pavel Rappo pavel.ra...@oracle.com:

There is at least one method in the JDK with similar characteristics: 
java.nio.file.Files#copy(java.io.InputStream, java.io.OutputStream)
But, (1) it has a private access (2) even if we made it public I doubt 
java.nio.file.Files would be a good place for it



I would suggest to introduce a separate IOUtil class holding such utility 
methods. Additionally to copyTo() and copyFrom() method could be added later 
for more intuitive usage. Also the copy method within the Files method could be 
replaced with a static reference to the IOUtil class.


Thanks to Pavel for pointing out the existing copy operations in the nio Files 
class. I think there's a case for the InputStream = OutputStream copy method to 
be placed there too, although I admit it is somewhat unusual in that it doesn't 
actually have anything to do with files.


At my first encounter with the nio.Files class some years ago I saw the 
following copying methods:


copy(istream, targetfile)
copy(sourcefile, ostream)
copy(sourcefile, targetfile)

and I immediately thought, Where is copy(istream, ostream)? So to me at least, 
it makes more sense to be in the Files class than in some newly created IOUtils 
class. (I'd like to hear further from Alan on this.)


As Pavel pointed out, the logic is also already there in the Files class. 
Probably the way to proceed would be to rename the existing (private) method to 
be something like copyInternal() and then create a new, public copy(istream, 
ostream) method that does argument checking before calling copyInternal().



P.S. The thing that confuses me though, is the progress consumer. I believe 
this feature is rarely needed (at least in a way you described it).
If you want to do something like this, you should probably go asynchronous with 
full blown solution like what they have in javax.swing.SwingWorker.

-Pavel


The method having a IntConsumer I have already discussed with some other 
colleagues and they suggested to better use a IntPredicate in order to have the 
possibility to interrupt the copy process, without having to interrupt any 
threads. Additionally there is still the possibility to use such a Predicate 
for counting the total or using the information for other possibilities.


I'd suggest starting simple with a copy(istream, ostream) operation and 
considering some kind of interruptible, progress-reporting operation separately. 
It would seem quite limiting if the *only* progress-reporting operation in the 
system were the stream copier. We'd want a way to apply such a mechanism to 
other long-running operations.


I think the progress update reports also need to be decoupled from the actual 
I/O operations. For example, the current buffer size in nio.Files is 8192 bytes. 
If the streams are connected to a fast network connection, this will result in 
thousands of calls to the predicate per second. On the other hand, if the buffer 
size were raised, and the streams are connected to a slow network connection -- 
like my home internet connection :-) -- that might result in too few callbacks 
per second.


How to report progress from a running operation is an interesting problem and 
it's worthy of considering, but a copying utility doesn't seem like quite the 
right place for it.


s'marks



Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-20 Thread Remi Forax


On 11/21/2014 04:05 AM, Stuart Marks wrote:

Hi Patrick,

Good to meet you in Antwerp!

On 11/20/14 10:30 AM, Patrick Reinhart wrote:

Am 20.11.2014 um 10:22 schrieb Pavel Rappo pavel.ra...@oracle.com:

There is at least one method in the JDK with similar 
characteristics: java.nio.file.Files#copy(java.io.InputStream, 
java.io.OutputStream)
But, (1) it has a private access (2) even if we made it public I 
doubt java.nio.file.Files would be a good place for it




I would suggest to introduce a separate IOUtil class holding such 
utility methods. Additionally to copyTo() and copyFrom() method could 
be added later for more intuitive usage. Also the copy method within 
the Files method could be replaced with a static reference to the 
IOUtil class.


Thanks to Pavel for pointing out the existing copy operations in the 
nio Files class. I think there's a case for the InputStream = 
OutputStream copy method to be placed there too, although I admit it 
is somewhat unusual in that it doesn't actually have anything to do 
with files.


At my first encounter with the nio.Files class some years ago I saw 
the following copying methods:


copy(istream, targetfile)
copy(sourcefile, ostream)
copy(sourcefile, targetfile)

and I immediately thought, Where is copy(istream, ostream)? So to me 
at least, it makes more sense to be in the Files class than in some 
newly created IOUtils class. (I'd like to hear further from Alan on 
this.)


As Pavel pointed out, the logic is also already there in the Files 
class. Probably the way to proceed would be to rename the existing 
(private) method to be something like copyInternal() and then create a 
new, public copy(istream, ostream) method that does argument checking 
before calling copyInternal().


P.S. The thing that confuses me though, is the progress consumer. I 
believe this feature is rarely needed (at least in a way you 
described it).
If you want to do something like this, you should probably go 
asynchronous with full blown solution like what they have in 
javax.swing.SwingWorker.


-Pavel


The method having a IntConsumer I have already discussed with some 
other colleagues and they suggested to better use a IntPredicate in 
order to have the possibility to interrupt the copy process, without 
having to interrupt any threads. Additionally there is still the 
possibility to use such a Predicate for counting the total or using 
the information for other possibilities.


I'd suggest starting simple with a copy(istream, ostream) operation 
and considering some kind of interruptible, progress-reporting 
operation separately. It would seem quite limiting if the *only* 
progress-reporting operation in the system were the stream copier. 
We'd want a way to apply such a mechanism to other long-running 
operations.


I think the progress update reports also need to be decoupled from the 
actual I/O operations. For example, the current buffer size in 
nio.Files is 8192 bytes. If the streams are connected to a fast 
network connection, this will result in thousands of calls to the 
predicate per second. On the other hand, if the buffer size were 
raised, and the streams are connected to a slow network connection -- 
like my home internet connection :-) -- that might result in too few 
callbacks per second.


How to report progress from a running operation is an interesting 
problem and it's worthy of considering, but a copying utility doesn't 
seem like quite the right place for it.


I also think you don't need a specific progress API given that you can 
write an InputStream that act as a proxy on top of the real inputStream 
and delegate the number of read bytes to a specific lambda.




s'marks



cheers,
Rémi



Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-20 Thread Patrick Reinhart
Hi Stuart,

 Am 21.11.2014 um 04:05 schrieb Stuart Marks stuart.ma...@oracle.com:
 
 Hi Patrick,
 
 Good to meet you in Antwerp!

The pleasure was all mine :-)

 On 11/20/14 10:30 AM, Patrick Reinhart wrote:
 Am 20.11.2014 um 10:22 schrieb Pavel Rappo pavel.ra...@oracle.com:
 
 There is at least one method in the JDK with similar characteristics: 
 java.nio.file.Files#copy(java.io.InputStream, java.io.OutputStream)
 But, (1) it has a private access (2) even if we made it public I doubt 
 java.nio.file.Files would be a good place for it
 
 
 I would suggest to introduce a separate IOUtil class holding such utility 
 methods. Additionally to copyTo() and copyFrom() method could be added later 
 for more intuitive usage. Also the copy method within the Files method could 
 be replaced with a static reference to the IOUtil class.
 
 Thanks to Pavel for pointing out the existing copy operations in the nio 
 Files class. I think there's a case for the InputStream = OutputStream copy 
 method to be placed there too, although I admit it is somewhat unusual in 
 that it doesn't actually have anything to do with files.
 
 At my first encounter with the nio.Files class some years ago I saw the 
 following copying methods:
 
copy(istream, targetfile)
copy(sourcefile, ostream)
copy(sourcefile, targetfile)
 
 and I immediately thought, Where is copy(istream, ostream)? So to me at 
 least, it makes more sense to be in the Files class than in some newly 
 created IOUtils class. (I’d like to hear further from Alan on this.)
 

The reason to not put those copy operations in the Files class in the first 
place, is the fact that this operation is not specific to files. If I would 
like to copy some database blob stream to the servlet output stream for 
example, there is no relation to a file at all. 


 As Pavel pointed out, the logic is also already there in the Files class. 
 Probably the way to proceed would be to rename the existing (private) method 
 to be something like copyInternal() and then create a new, public 
 copy(istream, ostream) method that does argument checking before calling 
 copyInternal().
 

My first idea was to even in fact, to some sort of copy function on the 
InputStream like „copyFrom(OutputStream)“ and on the OutputStream something 
like „copyTo(InputStream)“.  Those methods would use the copyInternal“ method 
on Files if the one would be made default access.

The same would the also apply to Reader/Writer of course, for which there would 
be the need to have a similar copy method.


 P.S. The thing that confuses me though, is the progress consumer. I believe 
 this feature is rarely needed (at least in a way you described it).
 If you want to do something like this, you should probably go asynchronous 
 with full blown solution like what they have in javax.swing.SwingWorker.
 
 -Pavel
 
 The method having a IntConsumer I have already discussed with some other 
 colleagues and they suggested to better use a IntPredicate in order to have 
 the possibility to interrupt the copy process, without having to interrupt 
 any threads. Additionally there is still the possibility to use such a 
 Predicate for counting the total or using the information for other 
 possibilities.
 
 I'd suggest starting simple with a copy(istream, ostream) operation and 
 considering some kind of interruptible, progress-reporting operation 
 separately. It would seem quite limiting if the *only* progress-reporting 
 operation in the system were the stream copier. We’d want a way to apply such 
 a mechanism to other long-running operations.

Agreed. I could implement some Input-/OutputFilterStream that could implement 
such a behavior, without having to do that on the API.

 I think the progress update reports also need to be decoupled from the actual 
 I/O operations. For example, the current buffer size in nio.Files is 8192 
 bytes. If the streams are connected to a fast network connection, this will 
 result in thousands of calls to the predicate per second. On the other hand, 
 if the buffer size were raised, and the streams are connected to a slow 
 network connection -- like my home internet connection :-) -- that might 
 result in too few callbacks per second.

I see your point for decoupling there. So it would be more practical to have 
the actual buffer size being optionally specified?  

- by the way: I also don’t have a real fast internet connection ;-)

 How to report progress from a running operation is an interesting problem and 
 it’s worthy of considering, but a copying utility doesn't seem like quite the 
 right place for it.

I see your point there.

Patrick





Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-19 Thread Patrick Reinhart


 Am 13.11.2014 um 20:59 schrieb Alan Bateman alan.bate...@oracle.com:
 
 On 13/11/2014 19:31, Patrick Reinhart wrote:
 Hi there,
 
 In the followup of a BOF with Stephen Colebourne with his ideas of small 
 library changes that may could get in JDK9. As of the fact that in the 
 codebase of my company there are several locations where we copy from/to IO 
 stream over and over again using either external libraries or do it by 
 ourselves,  I suggested to have some support for easy coping data between 
 Input-/OutputStream or Reader/Writer without having to use to external 
 libraries.
 
 Long overdue. I remember we prototyped methods like this (and much more) 
 during JDK 7 but didn't do enough at the time to actually get them in. We did 
 include a bunch of easy to use methods in the Files class at the time, 
 including copy between input/output streams and files, but we didn't 
 introduce an IOUtils or such class in java.io.



I did some implementation of a IOUtils class for the basic copy task already. 
Should I post a patch with the work I already done?

Best regards,

Patrick

Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-13 Thread Patrick Reinhart
Hi there,

In the followup of a BOF with Stephen Colebourne with his ideas of small 
library changes that may could get in JDK9. As of the fact that in the codebase 
of my company there are several locations where we copy from/to IO stream over 
and over again using either external libraries or do it by ourselves,  I 
suggested to have some support for easy coping data between Input-/OutputStream 
or Reader/Writer without having to use to external libraries.

My suggestion would look something like this:

try (InputStream in = … ; OutputStream out = …) {
  in.copyTo(out);
}

Or from the other end:

try (InputStream in = … ; OutputStream out = …) {
  out.copyFrom(in);
}

The same for character based streams:

try (Reader in = …; Writer out = …) {
  in.copyTo(out);
}

or

try (Reader in = …; Writer out = …) {
  out.copyFrom(in);
}


What do you think about this idea? I could imagine, that we could also pass a 
IntConsumer / LongConsumer in, that will be called with each amount of 
successfully copied amount of bytes/chars in case we need a total amount of 
data or displaying the progress of copy externally.

I’m looking forward to your opinions upon this proposal.

Cheers

Patrick 

Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-13 Thread Alan Bateman

On 13/11/2014 19:31, Patrick Reinhart wrote:

Hi there,

In the followup of a BOF with Stephen Colebourne with his ideas of small 
library changes that may could get in JDK9. As of the fact that in the codebase 
of my company there are several locations where we copy from/to IO stream over 
and over again using either external libraries or do it by ourselves,  I 
suggested to have some support for easy coping data between Input-/OutputStream 
or Reader/Writer without having to use to external libraries.

Long overdue. I remember we prototyped methods like this (and much more) 
during JDK 7 but didn't do enough at the time to actually get them in. 
We did include a bunch of easy to use methods in the Files class at the 
time, including copy between input/output streams and files, but we 
didn't introduce an IOUtils or such class in java.io.


-Alan



Re: Library enhancement proposal for copying data from/to Reader/Writer InputStream/OutputStream

2014-11-13 Thread Patrick Reinhart
Hi Alan,

Where would you suggest to put such methods though? Should we aim for a 
„IOUitls class holding such methods in the first place and eventually place 
some simple convenience methods on Input-/OutputStream and Reader/Writer?

I personally would do both, because I think it would make the usage more fluid 
from the usage perspective coming from a InputStream/Reader. 

Having said that, this leads me to the question: 

Are some other use cases where it would be good to have some sort of a callback 
in form of a function reference being called to notify about the amount of 
bytes/chars read and written to the target. This to have a hook for cases where 
we want to show either some sort of a progress or secondly sum of the total 
amount of transferred data. 

Also I think there should be may some possibility to stop the copy job on a 
„feedback“ event as follows:

while ((read=input.read(buffer)-1  proceedCheck.read(read)) {
output.write(buffer, 0, read);
}

Where proceedCheck would be a functional interface similar to the IntConsumer 
or LongConsumer but with a boolean return type signaling to keep on copying or 
terminate. (or there is a better approach using other functional interfaces, I 
missed so far)

Other opinions / input? I would be glad to help improve the library in this 
direction to finally get rid of lots of duplicated code copying data… 

Cheers Patrick


 Am 13.11.2014 um 20:59 schrieb Alan Bateman alan.bate...@oracle.com:
 
 On 13/11/2014 19:31, Patrick Reinhart wrote:
 Hi there,
 
 In the followup of a BOF with Stephen Colebourne with his ideas of small 
 library changes that may could get in JDK9. As of the fact that in the 
 codebase of my company there are several locations where we copy from/to IO 
 stream over and over again using either external libraries or do it by 
 ourselves,  I suggested to have some support for easy coping data between 
 Input-/OutputStream or Reader/Writer without having to use to external 
 libraries.
 
 Long overdue. I remember we prototyped methods like this (and much more) 
 during JDK 7 but didn't do enough at the time to actually get them in. We did 
 include a bunch of easy to use methods in the Files class at the time, 
 including copy between input/output streams and files, but we didn't 
 introduce an IOUtils or such class in java.io.
 
 -Alan