-
Notifications
You must be signed in to change notification settings - Fork 381
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Question about generating a digest value during sftp transfer #598
Comments
While using |
Good to know, thanks for the tip! |
Thank you Cassondra very much for the tips. We are indeed relying on the However, we also need a way to get both a hash and the file at the same time, because the source is not a physical file, but a pipe, while the destination is a remote file. So there is no way to generate the SHA out of a local file, but only a remote file, which will double the transfer data then! Do you have any suggestion on how we could overcome this? Is it possible to wrap the |
Is it possible to do in this way while performance of your code won't be affected?
|
I tested the above code and compared it with other approach, and confirmed that it has significantly reduced performance.
But as I said, we cannot do like #3 above, because in our case the local file is a pipe. |
I think, yeah, you should be able to wrap the Hm, you might also be able to use a |
Thanks Cassondra for the confirmation. Or you meant using |
Yeah, I meant using |
Hi Cassondra, I created a wrapper like this:
Then I used it like this:
But it still took 12 minutes to transfer that 900M file, while it took only 1 minute without the wrapper... |
Using the NewHashWriter like this is even slower, taking 14 minutes to tranfer.
|
Good news! Thank you for the help! |
So, yeah, either way the |
I played around with this some more and I actually got the best performance with this wrapper, the key being to impl the type HashReader struct {
size int64
r io.ReadCloser
h hash.Hash
}
func NewHashReader(r io.ReadCloser, size int64, h hash.Hash) HashReader {
return HashReader{size, r, h}
}
func NewHashReaderFile(path string, h hash.Hash) (HashReader, error) {
fh, err := os.Open(path)
if err != nil {
return HashReader{}, err
}
if stat, err := fh.Stat(); err != nil {
return HashReader{}, err
} else {
return NewHashReader(fh, stat.Size(), h), nil
}
}
func (ha HashReader) Read(p []byte) (int, error) {
n, err := ha.r.Read(p)
if n > 0 {
_, _ = ha.h.Write(p[:n])
}
return n, err
}
func (ha HashReader) Hash() []byte {
return ha.h.Sum(nil)
}
func (ha HashReader) HashStr() string {
return hex.EncodeToString(ha.Hash())
}
func (ha HashReader) Size() int64 {
return ha.size
}
func (ha HashReader) Close() error {
return ha.r.Close()
} Then just make sure you use |
Also do not wrap the |
I strongly recommend making your You also might want to use the |
I actually started with it as a pointer but making it a non-pointer lead to a consistent 30-40 mb/s increase in transfer speed (which surprised me I only tried it on a whim). And yeah it was necessary to use |
Huh… interesting. That’s something I wouldn’t have expected. |
Please advice on how to generate a digest (specifically, the Sha256 value) of the file being transferred via this sftp tool?
The counterpart in Java is like this:
I know that to generate the Sha256 of a local file, the Go code would be like this:
But how to get that during the sftp transfer?
BTW, currently I wrote code like below to do file transfer (error handling being removed just to show the major logic):
or
Thank you in advance.
The text was updated successfully, but these errors were encountered: