I posted this also to ask.clojure.org forum at 
https://ask.clojure.org/index.php/8450/strange-behavior-with-clojure-java-io-copy

On Sunday, August 25, 2019 at 8:05:57 PM UTC+3, Juha Syrjälä wrote:
>
> Hi,
>
> I found a strange behavior in implementation of clojure.java.io/copy 
> function
>
>
> https://github.com/clojure/clojure/blob/ee1b606ad066ac8df2efd4a6b8d0d365c206f5bf/src/clj/clojure/java/io.clj#L391
> (defn copy
>   "Copies input to output.  Returns nil or throws IOException.
>   Input may be an InputStream, Reader, File, byte[], char[], or String.
>   Output may be an OutputStream, Writer, or File.
>   Options are key/value pairs and may be one of
>     :buffer-size  buffer size to use, default is 1024.
>     :encoding     encoding to use if converting between
>                   byte and char streams.   
>   Does not close any streams except those it opens itself 
>   (on a File)."
>   {:added "1.2"}
>   [input output & opts]
>   (do-copy input output (when opts (apply hash-map opts))))
>
> Actual copying is implemented here when copying from an InputStream to an 
> OutputStream.
>
>
> https://github.com/clojure/clojure/blob/ee1b606ad066ac8df2efd4a6b8d0d365c206f5bf/src/clj/clojure/java/io.clj#L306
> (defmethod do-copy [InputStream OutputStream] [^InputStream input 
> ^OutputStream output opts]
>   (let [buffer (make-array Byte/TYPE (buffer-size opts))]
>     (loop []
>       (let [size (.read input buffer)]  ;;; XXX point 1
>         (when (pos? size)               ;;; XXX point 2
>           (do (.write output buffer 0 size)
>               (recur)))))))
>
> Here .read function at point 1 is 
> https://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html#read(byte[])
>
> The javadoc states following
>
> Reads some number of bytes from the input stream and stores them into the 
> buffer array b. The number of bytes actually read is returned as an 
> integer. This method blocks until input data is available, end of file is 
> detected, or an exception is thrown.
>
> If the length of b is zero, then no bytes are read and 0 is returned; 
> otherwise, there is an attempt to read at least one byte. If no byte is 
> available because the stream is at the end of the file, the value -1 is 
> returned; otherwise, at least one byte is read and stored into b.
>
> --- 
>
>
> Meaning that return value -1 means end of stream, and return value 0 
> doesn't mean end of stream. However condition at point 2 in code above, 
> stops recursion when .read returns value that is smaller than 1.
>
>
> Now consider a case where .read returns this sequence of values in 
> consecutive calls:
>
>
> 1024, 0, 1024, 201, -1
>
>
> clojure.java/io copies only the first 1024 bytes, when the whole stream 
> has 2249 bytes. Is this the intended behavior? Should the condition at 
> point 1 be "(not (neg? size))" ?
>
>
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/039a4a5d-75d3-4da9-8da1-d3af340989cc%40googlegroups.com.

Reply via email to