确定输入流的大小

发布于 2024-07-27 00:30:44 字数 759 浏览 4 评论 0原文

我目前的情况是:我必须读取一个文件并将内容放入InputStream中。 之后,我需要将 InputStream 的内容放入字节数组中,这需要(据我所知)InputStream 的大小。 有任何想法吗?

根据要求,我将显示我从上传的文件创建的输入流

InputStream uploadedStream = null;
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
java.util.List items = upload.parseRequest(request);      
java.util.Iterator iter = items.iterator();

while (iter.hasNext()) {
    FileItem item = (FileItem) iter.next();
    if (!item.isFormField()) {
        uploadedStream = item.getInputStream();
        //CHANGE uploadedStreambyte = item.get()
    }
}

该请求是一个 HttpServletRequest 对象,它类似于 FileItemFactory 和 ServletFileUpload code> 来自 Apache Commons FileUpload 包。

My current situation is: I have to read a file and put the contents into InputStream. Afterwards I need to place the contents of the InputStream into a byte array which requires (as far as I know) the size of the InputStream. Any ideas?

As requested, I will show the input stream that I am creating from an uploaded file

InputStream uploadedStream = null;
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
java.util.List items = upload.parseRequest(request);      
java.util.Iterator iter = items.iterator();

while (iter.hasNext()) {
    FileItem item = (FileItem) iter.next();
    if (!item.isFormField()) {
        uploadedStream = item.getInputStream();
        //CHANGE uploadedStreambyte = item.get()
    }
}

The request is a HttpServletRequest object, which is like the FileItemFactory and ServletFileUpload is from the Apache Commons FileUpload package.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

倾听心声的旋律 2024-08-03 00:30:44

这是一个非常古老的线程,但当我用谷歌搜索这个问题时,它仍然是第一个弹出的东西。 所以我只想补充一点:

InputStream inputStream = conn.getInputStream();
int length = inputStream.available();

为我工作。 而且比这里的其他答案简单得多。

警告 此解决方案无法提供有关流总大小的可靠结果。 除了 JavaDoc 之外:

请注意,虽然 {@code InputStream} 的某些实现将返回
* 流中的总字节数,很多不会。

This is a REALLY old thread, but it was still the first thing to pop up when I googled the issue. So I just wanted to add this:

InputStream inputStream = conn.getInputStream();
int length = inputStream.available();

Worked for me. And MUCH simpler than the other answers here.

Warning This solution does not provide reliable results regarding the total size of a stream. Except from the JavaDoc:

Note that while some implementations of {@code InputStream} will return
* the total number of bytes in the stream, many will not.

是伱的 2024-08-03 00:30:44

我会读入 ByteArrayOutputStream 然后调用toByteArray() 获取结果字节数组。 您不需要提前定义大小(尽管如果您知道的话这可能是一种优化。在很多情况下您不会)

I would read into a ByteArrayOutputStream and then call toByteArray() to get the resultant byte array. You don't need to define the size in advance (although it's possibly an optimisation if you know it. In many cases you won't)

回眸一笑 2024-08-03 00:30:44

如果不读取流,则无法确定流中的数据量; 但是,您可以询问文件的大小:

http://java.sun.com/javase/6/docs/api/java/io/File.html#length()

如果不可能,您可以写入您想要的字节从输入流读取到 ByteArrayOutputStream将根据需要增长。

You can't determine the amount of data in a stream without reading it; you can, however, ask for the size of a file:

http://java.sun.com/javase/6/docs/api/java/io/File.html#length()

If that isn't possible, you can write the bytes you read from the input stream to a ByteArrayOutputStream which will grow as required.

土豪我们做朋友吧 2024-08-03 00:30:44

我只是想补充一点,Apache Commons IO 具有流支持实用程序来执行复制。 (顺便说一句,将文件放入输入流是什么意思?您可以向我们展示您的代码吗?)

编辑:

好的,您想如何处理该项目的内容?
有一个 item.get() 它返回字节数组中的整个内容。

Edit2

item.getSize() 将返回上传的文件大小

I just wanted to add, Apache Commons IO has stream support utilities to perform the copy. (Btw, what do you mean by placing the file into an inputstream? Can you show us your code?)

Edit:

Okay, what do you want to do with the contents of the item?
There is an item.get() which returns the entire thing in a byte array.

Edit2

item.getSize() will return the uploaded file size.

要走干脆点 2024-08-03 00:30:44

对于输入流

org.apache.commons.io.IoUtils.toByteArray(inputStream).length()

对于可选< 多部分文件>

Stream.of(multipartFile.get()).mapToLong(file->file.getSize()).findFirst().getAsLong()

For InputStream

org.apache.commons.io.IoUtils.toByteArray(inputStream).length()

For Optional < MultipartFile >

Stream.of(multipartFile.get()).mapToLong(file->file.getSize()).findFirst().getAsLong()
不交电费瞎发啥光 2024-08-03 00:30:44

下面的函数应该适用于任何InputStream。 正如其他答案所暗示的那样,如果不通读它,您就无法可靠地找到 InputStream 的长度,但与其他答案不同的是,您不应该尝试保存整个流通过读入 ByteArrayOutputStream 来存储在内存中,也没有任何理由这样做。 理想情况下,您应该依赖其他 API 来获取流大小,而不是读取流,例如使用 File API 获取文件的大小。

public static int length(InputStream inputStream, int chunkSize) throws IOException {
    byte[] buffer = new byte[chunkSize];
    int chunkBytesRead = 0;
    int length = 0;
    while((chunkBytesRead = inputStream.read(buffer)) != -1) {
        length += chunkBytesRead;
    }
    return length;
}

chunkSize选择一个适合InputStream类型的合理值。 例如,从磁盘读取数据时,如果 chunkSize 的值太小,效率会很低。

The function below should work with any InputStream. As other answers have hinted, you can't reliably find the length of an InputStream without reading through it, but unlike other answers, you should not attempt to hold the entire stream in memory by reading into a ByteArrayOutputStream, nor is there any reason to. Instead of reading the stream, you should ideally rely on other API for stream sizes, for example getting the size of a file using the File API.

public static int length(InputStream inputStream, int chunkSize) throws IOException {
    byte[] buffer = new byte[chunkSize];
    int chunkBytesRead = 0;
    int length = 0;
    while((chunkBytesRead = inputStream.read(buffer)) != -1) {
        length += chunkBytesRead;
    }
    return length;
}

Choose a reasonable value for chunkSize appropriate to the kind of InputStream. E.g. reading from disk it would not be efficient to have too small a value for chunkSize.

忆梦 2024-08-03 00:30:44

您可以使用 Utils.java 的 getBytes(inputStream) 获取 InputStream 的大小,请检查以下链接

从输入流获取字节

you can get the size of InputStream using getBytes(inputStream) of Utils.java check this following link

Get Bytes from Inputstream

桃扇骨 2024-08-03 00:30:44

当显式处理 ByteArrayInputStream 时,与本页上的一些注释相反,您可以使用 .available() 函数来获取大小。 只需在开始阅读之前执行此操作即可。

来自 JavaDocs:

返回可以读取(或跳过)的剩余字节数
over) 来自此输入流。 返回的值为count - pos,其中
是要从输入缓冲区读取的剩余字节数。

https://docs.oracle。 com/javase/7/docs/api/java/io/ByteArrayInputStream.html#available()

When explicitly dealing with a ByteArrayInputStream then contrary to some of the comments on this page you can use the .available() function to get the size. Just have to do it before you start reading from it.

From the JavaDocs:

Returns the number of remaining bytes that can be read (or skipped
over) from this input stream. The value returned is count - pos, which
is the number of bytes remaining to be read from the input buffer.

https://docs.oracle.com/javase/7/docs/api/java/io/ByteArrayInputStream.html#available()

甜嗑 2024-08-03 00:30:44

如果您知道您的 InputStreamFileInputStreamByteArrayInputStream,则可以使用一点反射来获取流大小而无需阅读全部内容。 这是一个示例方法:

static long getInputLength(InputStream inputStream) {
    try {
        if (inputStream instanceof FilterInputStream) {
            FilterInputStream filtered = (FilterInputStream)inputStream;
            Field field = FilterInputStream.class.getDeclaredField("in");
            field.setAccessible(true);
            InputStream internal = (InputStream) field.get(filtered);
            return getInputLength(internal);
        } else if (inputStream instanceof ByteArrayInputStream) {
            ByteArrayInputStream wrapper = (ByteArrayInputStream)inputStream;
            Field field = ByteArrayInputStream.class.getDeclaredField("buf");
            field.setAccessible(true);
            byte[] buffer = (byte[])field.get(wrapper);
            return buffer.length;
        } else if (inputStream instanceof FileInputStream) {
            FileInputStream fileStream = (FileInputStream)inputStream;
            return fileStream.getChannel().size();
        }
    } catch (NoSuchFieldException | IllegalAccessException | IOException exception) {
        // Ignore all errors and just return -1.
    }
    return -1;
}

我确信这可以扩展以支持额外的输入流。

If you know that your InputStream is a FileInputStream or a ByteArrayInputStream, you can use a little reflection to get at the stream size without reading the entire contents. Here's an example method:

static long getInputLength(InputStream inputStream) {
    try {
        if (inputStream instanceof FilterInputStream) {
            FilterInputStream filtered = (FilterInputStream)inputStream;
            Field field = FilterInputStream.class.getDeclaredField("in");
            field.setAccessible(true);
            InputStream internal = (InputStream) field.get(filtered);
            return getInputLength(internal);
        } else if (inputStream instanceof ByteArrayInputStream) {
            ByteArrayInputStream wrapper = (ByteArrayInputStream)inputStream;
            Field field = ByteArrayInputStream.class.getDeclaredField("buf");
            field.setAccessible(true);
            byte[] buffer = (byte[])field.get(wrapper);
            return buffer.length;
        } else if (inputStream instanceof FileInputStream) {
            FileInputStream fileStream = (FileInputStream)inputStream;
            return fileStream.getChannel().size();
        }
    } catch (NoSuchFieldException | IllegalAccessException | IOException exception) {
        // Ignore all errors and just return -1.
    }
    return -1;
}

This could be extended to support additional input streams, I am sure.

迷爱 2024-08-03 00:30:44

如果您需要将数据流式传输到另一个不允许您直接确定大小的对象(例如javax.imageio.ImageIO),那么您可以包装您的InputStream在 CountingInputStream (Apache Commons IO),然后读取大小:

CountingInputStream countingInputStream = new CountingInputStream(inputStream);
// ... process the whole stream ...
int size = countingInputStream.getCount();

If you need to stream the data to another object that doesn't allow you to directly determine the size (e.g. javax.imageio.ImageIO), then you can wrap your InputStream within a CountingInputStream (Apache Commons IO), and then read the size:

CountingInputStream countingInputStream = new CountingInputStream(inputStream);
// ... process the whole stream ...
int size = countingInputStream.getCount();
一抹微笑 2024-08-03 00:30:44

添加到您的 pom.xml:

  <dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.5</version>
  </dependency>

用于获取内容类型长度(InputStream 文件):

IOUtils.toByteArray(file).length

Add to your pom.xml:

  <dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.5</version>
  </dependency>

Use to get the content type lenght (InputStream file):

IOUtils.toByteArray(file).length
薄凉少年不暖心 2024-08-03 00:30:44

如果您想忽略内容并只获取流的长度(以字节为单位),那么您可以这样做(从 Java 11 开始)。

长长度 = inputStream.transferTo(OutputStream.nullOutputStream())

If you want to ignore the contents and just get the length of the stream (in bytes) then you can do this (since Java 11).

long length = inputStream.transferTo(OutputStream.nullOutputStream())

幽梦紫曦~ 2024-08-03 00:30:44

使用这个方法,你只需要传递InputStream

public String readIt(InputStream is) {
    if (is != null) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(is, "utf-8"), 8);

        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            sb.append(line).append("\n");
        }
        is.close();
        return sb.toString();
    }
    return "error: ";
}

Use this method, you just have to pass the InputStream

public String readIt(InputStream is) {
    if (is != null) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(is, "utf-8"), 8);

        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            sb.append(line).append("\n");
        }
        is.close();
        return sb.toString();
    }
    return "error: ";
}
放我走吧 2024-08-03 00:30:44
    try {
        InputStream connInputStream = connection.getInputStream();
    } catch (IOException e) {
        e.printStackTrace();
    }

    int size = connInputStream.available();

int 可用 ()
返回可以从此输入流读取(或跳过)的字节数的估计值,而不会被该输入流的方法的下一次调用所阻塞。 下一次调用可能是同一个线程或另一个线程。 单次读取或跳过这么多字节不会阻塞,但可能会读取或跳过更少的字节。

InputStream - Android SDK | Android 开发者

    try {
        InputStream connInputStream = connection.getInputStream();
    } catch (IOException e) {
        e.printStackTrace();
    }

    int size = connInputStream.available();

int available ()
Returns an estimate of the number of bytes that can be read (or skipped over) from this input stream without blocking by the next invocation of a method for this input stream. The next invocation might be the same thread or another thread. A single read or skip of this many bytes will not block, but may read or skip fewer bytes.

InputStream - Android SDK | Android Developers

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文