简体   繁体   English

从 InputStream 获取大小的最低影响方法

[英]Lowest impact method of getting size from InputStream

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.我正在尝试获取 InputStream 的大小以用作与文件传输的比较,以确保传输所有文件数据。 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.我正在使用 Jcraft 的 ChannelSftp 和 SftpProgressMonitor,但是SftpProgressMonitor.init()没有为 InputStreams 提供max ,所以我想在内部找到它。

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.在系统的这一点上,我知道 InputStream 不会被进一步写入,我无法轻松访问原始文件以读取该大小,并且我已经看到许多其他读取到字节数组的实现或字节数组输出流。 What method would have the least overall impact on the system if I want to maintain an InputStream for the actual SFTP calls?如果我想为实际的 SFTP 调用维护 InputStream,哪种方法对系统的整体影响最小? The files being written can be quite large (into 1+ GB) so a simple implementation might have significant impact.正在写入的文件可能非常大(超过 1 GB),因此简单的实现可能会产生重大影响。

In the context of using the JSch API, before calling ChannelSftp.get() you can call ChannelSftp.lstat() .在使用 JSch API 的上下文中,在调用 ChannelSftp.get() 之前,您可以调用ChannelSftp.lstat()

This returns a SftpATTRS object which contains a .getSize() method which returns the size of the file in bytes.这将返回一个SftpATTRS 对象,其中包含一个 .getSize() 方法,该方法返回文件的大小(以字节为单位)。 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基于@Michael 的建议

Here's how we can do in kotlin这是我们在 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")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM