确定InputStream的大小

时间:2009-07-13 13:05:34

标签: java arrays size inputstream

我目前的情况是:我必须阅读文件并将内容放入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来自Apache Commons FileUpload包。

11 个答案:

答案 0 :(得分:35)

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

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

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

答案 1 :(得分:33)

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

答案 2 :(得分:16)

您无法在不读取数据的情况下确定数据量;但是,您可以询问文件的大小:

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

如果无法做到这一点,您可以将从输入流中读取的字节写入ByteArrayOutputStream,这将根据需要增长。

答案 3 :(得分:12)

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

修改

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

<强> EDIT2

item.getSize()将返回上传的file size

答案 4 :(得分:4)

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

Get Bytes from Inputstream

答案 5 :(得分:2)

对于InputStream

package sample;

import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;


public class Controller {
    @FXML
    private Label label;
    @FXML
    private TextField weightText;
    @FXML
    private TextField heightText;
    @FXML
    private Label label2;

    @FXML
    public void count() {

        double bmi = 0;
        int bmi2 = 0;
        double weight = 0;
        double height = 0;
        label2.setText("");


        try {
            weight = Double.parseDouble(weightText.getText());
            height = Double.parseDouble(heightText.getText());

            if (weight > 0 && wzrost > 0) {
                bmi = (weight / (height* height)) * 100;
                bmi2 = (int) bmi;
                bmi = (double) bmi2 / 100;
                if (bmi > 30) {
                    label.setText("Your'e too fat. Your bmi is:  " + bmi);
                } else if (bmi > 25 && bmi < 30) {
                    label.setText("Little to much weight. Your bmi is: "+bmi);
                } else if (bmi > 18.5 && bmi < 25) {
                    label.setText("Great shape. Your bmi is: " + bmi);
                } else {
                    label.setText("Your'e to skinny.Your bmi is:" + bmi);
                }
            } else {
                label.setText("Wrong values");
            }

        } catch (Exception e) {
            label2.setText("Use dot");
            label.setText("Wrong values!");
        }
    }
}

对于可选的

IoUtils.toByteArray(inputStream).length

答案 6 :(得分:2)

下面的函数应该适用于任何 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 的值太小会效率低下。

答案 7 :(得分:0)

当明确处理ByteArrayInputStream时,与此页面上的某些评论相反,您可以使用.available()函数来获取大小。在你开始阅读它之前必须这样做。

来自JavaDocs:

  

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

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

答案 8 :(得分:0)

如果您知道自己的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;
}

我敢肯定,它可以扩展为支持其他输入流。

答案 9 :(得分:-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: ";
}

答案 10 :(得分:-1)

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

    int size = connInputStream.available();

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

InputStream - Android SDK | Android Developers