奇怪的byte []的行为读取URL(Strange byte[] behavior reading

2019-09-23 11:24发布

最后,我的终极目标是:

  • 从URL中读取(这个问题是关于什么的)
  • 保存在一个数据库检索[PDF]内容的BLOB字段(已经是板上钉钉了)
  • 从BLOB字段阅读和内容附加到电子邮件
  • 所有这些都不要去一个文件系统

用下面的方法的目标是获得一个byte[]可以下游使用作为电子邮件附件(以避免写入磁盘):

public byte[] retrievePDF() {

         HttpClient httpClient = new HttpClient();

         GetMethod httpGet = new GetMethod("http://website/document.pdf");
         httpClient.executeMethod(httpGet);
         InputStream is = httpGet.getResponseBodyAsStream();

         byte[] byteArray = new byte[(int) httpGet.getResponseContentLength()];

         is.read(byteArray, 0, byteArray.length);

        return byteArray;
}

对于一个特定的PDF,所述getResponseContentLength()方法返回101689作为长度。 奇怪的是,如果设置了一个断点和询问byteArray变量,它具有101689个字节元素,但是,之后字节#3744的阵列的剩余字节是全零( 0 )。 所产生的PDF则不是由PDF阅读器客户端可读,如Adobe阅读器。

为什么会发生呢?

通过浏览器检索该相同的PDF并且保存到磁盘,或使用类似下面的方法(这是我的后图案化的回答这个StackOverflow的交 ),导致可读PDF:

public void retrievePDF() {
    FileOutputStream fos = null;
    URL url;
    ReadableByteChannel rbc = null;

    url = new URL("http://website/document.pdf");

    DataSource urlDataSource = new URLDataSource(url);

    /* Open a connection, then set appropriate time-out values */
    URLConnection conn = url.openConnection();
    conn.setConnectTimeout(120000);
    conn.setReadTimeout(120000);

    rbc = Channels.newChannel(conn.getInputStream());

    String filePath = "C:\\temp\\";
    String fileName = "testing1234.pdf";
    String tempFileName = filePath + fileName;

    fos = new FileOutputStream(tempFileName);
    fos.getChannel().transferFrom(rbc, 0, 1 << 24);
    fos.flush();

    /* Clean-up everything */
    fos.close();
    rbc.close();
}

对于这两种方法,生成的PDF的大小做一个右键单击时101689字节>属性...在Windows中。

为什么会字节数组主要通过“一站式”部分呢?

Answer 1:

InputStream.read读取多达byteArray.length字节,但可能不准确读数为多。 它返回它有多少字节读取。 你应该重复调用它来完全读取数据,如下所示:

int bytesRead = 0;
while (true) {
    int n = is.read(byteArray, bytesRead, byteArray.length);
    if (n == -1) break;
    bytesRead += n;
}


Answer 2:

检查的返回值InputStream.read 。 它不会一气呵成读取所有。 你必须写一个循环。 或者,更好的是,使用Apache下议院IO复制的数据流。



Answer 3:

101689 = 2 ^ 16 + 36153所以它看起来像,存在于缓冲区大小为16比特界限。 36153和3744之间的差值也许从已经被读入一个额外的小1K缓冲器或所以标题部分,并已含有一些字节茎。



文章来源: Strange byte[] behavior reading from a URL