【问题标题】:InputStream reader输入流阅读器
【发布时间】:2014-10-31 20:05:03
【问题描述】:

我目前正在尝试从服务器读取图像文件,但得到的数据不完整或

Exception in thread "main" 
         java.lang.NegativeArraySizeException. 

这与缓冲区大小有关吗?我尝试使用静态大小而不是 contentlength。请多多指教。

  URL myURL = new URL(url);
  HttpURLConnection connection = (HttpURLConnection)myURL.openConnection();
  connection.setRequestMethod("GET");
  status = connection.getResponseCode();

  if (status == 200)
  {
    int size = connection.getContentLength() + 1024;
    byte[] bytes = new byte[size];
    InputStream input = new ByteArrayInputStream(bytes);
    FileOutputStream out = new FileOutputStream(file);
    input = connection.getInputStream();

    int data = input.read(bytes);
    while(data != -1){
       out.write(bytes);
       data = input.read(bytes);
    }
    out.close();
    input.close();

【问题讨论】:

    标签: java inputstream fileinputstream


    【解决方案1】:

    让我们检查一下代码:

    int size = connection.getContentLength() + 1024;
    byte[] bytes = new byte[size];
    

    为什么要增加 1024 字节的大小?重点是什么?缓冲区大小应该足够大以避免过多的读取,但要足够小以避免消耗过多的内存。例如,将其设置为 4096。

    InputStream input = new ByteArrayInputStream(bytes);
    FileOutputStream out = new FileOutputStream(file);
    input = connection.getInputStream();
    

    为什么你创建一个 ByteArrayInputStream,然后完全忘记它?您不需要 ByteArrayInputStream,因为您不是从字节数组中读取,而是从连接的输入流中读取。

    int data = input.read(bytes);
    

    这会从输入中读取字节。 ma​​x 读取的字节数是字节数组的长度。 实际读取的字节数被返回并存储在data中。

    while (data != -1) {
        out.write(bytes);
        data = input.read(bytes);
    }
    

    所以您已经读取了data 字节,但您并没有只写入数组的第一个data 字节。您写入整个字节数组。那是错的。假设您的数组大小为 4096 且数据为 400,而不是写入已读取的 400 个字节,而是写入 400 个字节 + 数组的剩余 3696 个字节,这可能是 0,或者可能具有来自先前的值读。应该是

    out.write(bytes, 0, data);
    

    最后:

    out.close();
    input.close();
    

    如果之前发生任何异常,这两个流将永远不会关闭。这样做几次,您的整个操作系统将不再有可用的文件描述。使用try-with-resources 语句确保您的流已关闭,无论发生什么。

    【讨论】:

      【解决方案2】:

      这段代码可以帮助你

      input = connection.getInputStream();
      byte[] buffer = new byte[4096];
      int n = - 1;
      
      OutputStream output = new FileOutputStream( file );
      while ( (n = input.read(buffer)) != -1)
      {
          if (n > 0)
          {
              output.write(buffer, 0, n);
          }
      }
      output.close();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-08-21
        • 2012-05-03
        • 2016-02-25
        • 2012-08-07
        • 1970-01-01
        • 2013-06-30
        • 1970-01-01
        • 2015-08-16
        相关资源
        最近更新 更多