I am trying to get the size of an InputStream for use as a comparison against a file transfer, to ensure that all file data is transferred. I'm using Jcraft's ChannelSftp and SftpProgressMonitor, but SftpProgressMonitor.init()
does not provide max
for InputStreams, so I'd like to find it internally.
At this point in the system, I know that the InputStream will not be written to any further, I can't easily access the original file to read that size, and I've seen many of the other implementations that read into a byte array or ByteArrayOutputStream. What method would have the least overall impact on the system if I want to maintain an InputStream for the actual SFTP calls? The files being written can be quite large (into 1+ GB) so a simple implementation might have significant impact.
In the context of using the JSch API, before calling ChannelSftp.get() you can call ChannelSftp.lstat() .
This returns a SftpATTRS object which contains a .getSize() method which returns the size of the file in bytes. This should tell you how many bytes you need to get in order to retrieve the entire file.
Just keep in mind if the files you're getting are changing in size frequently there could be a race condition between getting the file size and starting the file transfer. So this method should be fine if you're simply using this as a progress indicator, but if you're allocating static buffers or something like that you may need to rethink your approach.
Based on @Michael's suggestion
Here's how we can do in kotlin
val session: Session = getSession() // Jsch Session
session.connect()
val channel = session.openChannel("sftp") as ChannelSftp
channel.connect()
val contentSize: Long = channel.lstat("/upload/some_file.csv").size
val inputStream = channel.get("/upload/some_file.csv")
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.