I'm writing a helper utility to ease SFTP-uploads of large files to a remote server. In addition to the actual transfer (which command-line sftp or scp could accomplish), the utility is supposed to print the SHA256 of each file.
The files are large and the "local" storage of them is, actually, a slow NFS-mount -- so I don't want to re-read them again for the checksum. While the buffer is in memory, it can be both digested and pushed to the remote.
So, my code does:
async def upload(fName, SFTP):
inp = open(fName, "rb")
digest = hashlib.sha256()
bsize = os.stat(inp.fileno()).st_blksize
out = SFTP.open(os.path.split(fName)[-1], "w")
while True:
buf = inp.read(bsize)
if not buf:
break
digest.update(buf)
out.write(buf)
inp.close()
out.close()
print('SHA256 (%s) = %s' % (fName, digest.hexdigest()))
This, actually, works -- and multiple instances of upload are running over multiple SFTP-connections.
But it annoys me, that the CPU-intensive digest.update() is not in parallel with the I/O-bound out.write(). Can the two be parallelized?
How about the two open calls -- the local input and the remote output?