92

我目前的情况是:我必须读取一个文件并将内容放入InputStream. 之后我需要InputStreamInputStream. 有任何想法吗?

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

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对象,类似于Apache Commons FileUpload 包FileItemFactoryServletFileUpload

4

12 回答 12

78

这是一个非常古老的线程,但是当我用谷歌搜索这个问题时,它仍然是第一件事。所以我只想添加这个:

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

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

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

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

于 2013-08-14T16:30:07.737 回答
39

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

于 2009-07-13T13:10:13.553 回答
22

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

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

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

于 2009-07-13T13:09:11.650 回答
17

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

编辑:

好的,你想对项目的内容做什么?有一个在字节数组item.get() 中返回整个事物。

编辑2

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

于 2009-07-13T13:12:19.950 回答
8

对于输入流

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

对于可选的 < MultipartFile >

Stream.of(multipartFile.get()).mapToLong(file->file.getSize()).findFirst().getAsLong()
于 2018-11-23T13:59:55.860 回答
4

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

从输入流中获取字节

于 2013-03-21T12:11:56.473 回答
2

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

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

于 2021-03-02T04:47:12.760 回答
1

当显式处理一个ByteArrayInputStream然后与此页面上的某些评论相反的时候,您可以使用该.available()函数来获取大小。只需要在开始阅读之前完成它。

来自 JavaDocs:

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

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

于 2017-09-22T10:05:25.790 回答
1

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

CountingInputStream countingInputStream = new CountingInputStream(inputStream);
// ... process the whole stream ...
int size = countingInputStream.getCount();
于 2021-12-12T19:32:45.720 回答
0

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

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;
}

我敢肯定,这可以扩展为支持额外的输入流。

于 2019-04-10T18:24:58.570 回答
-1

使用这个方法,你只需要通过 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: ";
}
于 2015-11-10T23:17:04.203 回答
-2
    try {
        InputStream connInputStream = connection.getInputStream();
    } catch (IOException e) {
        e.printStackTrace();
    }

    int size = connInputStream.available();

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

InputStream - Android SDK | 安卓开发者

于 2017-12-05T15:56:05.633 回答