// If dst implements the ReaderFrom interface,
 // the copy is implemented using it.
 func CopyN(dst Writer, src Reader, n int64) (written int64, err error) {
-       written, err = Copy(dst, LimitReader(src, n))
+       written, err = copyN(dst, src, n)
        if written == n {
                return n, nil
        }
        return
 }
 
+// copyN copies n bytes (or until an error) from src to dst.
+// It returns the number of bytes copied and the earliest
+// error encountered while copying.
+//
+// If dst implements the ReaderFrom interface,
+// the copy is implemented using it.
+func copyN(dst Writer, src Reader, n int64) (int64, error) {
+       // If the writer has a ReadFrom method, use it to do the copy.
+       if rt, ok := dst.(ReaderFrom); ok {
+               return rt.ReadFrom(LimitReader(src, n))
+       }
+
+       l := 32 * 1024 // same size as in copyBuffer
+       if n < int64(l) {
+               l = int(n)
+       }
+       buf := make([]byte, l)
+
+       var written int64
+       for n > 0 {
+               if n < int64(len(buf)) {
+                       buf = buf[:n]
+               }
+
+               nr, errR := src.Read(buf)
+               if nr > 0 {
+                       n -= int64(nr)
+                       nw, errW := dst.Write(buf[:nr])
+                       if nw > 0 {
+                               written += int64(nw)
+                       }
+                       if errW != nil {
+                               return written, errW
+                       }
+                       if nr != nw {
+                               return written, ErrShortWrite
+                       }
+               }
+
+               if errR != nil {
+                       if errR != EOF {
+                               return written, errR
+                       }
+                       return written, nil
+               }
+       }
+       return written, nil
+}
+
 // Copy copies from src to dst until either EOF is reached
 // on src or an error occurs. It returns the number of bytes
 // copied and the first error encountered while copying, if any.