【问题标题】:Losing content in InputStream after performing operation执行操作后在 InputStream 中丢失内容
【发布时间】:2021-04-27 01:19:42
【问题描述】:

我正在使用外部扫描工具执行数据检查。在此过程中,我将 InputStream 传递给扫描工具。该工具扫描流并以布尔值响应。使用这个布尔值,我将决定是否要将流保存到文件中。在此过程中,该工具不会重置输入流,而是处于 EOF 状态。这使它无法使用。因此我创建的文件将有 0 字节。

我无法更改执行此操作的工具。所以我需要找到一种不影响 InputStream 内容的方法。但同时对输入流进行扫描和写入。

这是我的代码,

    FileOutputStream fos = null;
    ReadableByteChannel rbc = null;
    try {
        log.info(masterId + " : DOWNLOADING FILE FROM [ " + url + " ]");

        HttpURLConnection httpcon = (HttpURLConnection) urlConnection;
        //rbc = Channels.newChannel(httpcon.getInputStream());  -- this was my another approach
        //InputStream inputStream = Channels.newInputStream(rbc);
        if (!scanTool.scan(IOUtils.toByteArray(httpcon.getInputStream()))) {
            // exit with fail code
        }
        rbc = Channels.newChannel(httpcon.getInputStream());
        fos = new FileOutputStream(filePath);
        fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
        fos.close();
        rbc.close();
        return 1;
    } catch (FileNotFoundException ex) {
        //Handle exception
    }

在上面的代码sn-p中,

        if (!scanTool.scan(IOUtils.toByteArray(httpcon.getInputStream()))) {
            // exit with fail code
        }

这是我的新插入。我正在调用 scanTool 来执行检查条件的操作,只有当它通过时才继续写入文件。现在,在执行此操作时,我丢失了 inputStream 中的内容。

我在这里缺少什么。我什至尝试使用 BufferedInputSteam。还是不行。还尝试了另一种方法,我构造新的可读字节通道,然后从中构造新的 InputStream。如注释代码所示。但没有果实。

【问题讨论】:

    标签: java arrays inputstream httpurlconnection fileoutputstream


    【解决方案1】:

    鉴于您已经将 InputStream 转换为 byte[],您可以在扫描后写出相同的字节数组:

    byte[] bytes = IOUtils.toByteArray(httpcon.getInputStream());
    if (!scanTool.scan(bytes)) {
            // exit with fail code
    }
    try(FileOutputStream fos = new FileOutputStream(filePath)) {
        fos.write(bytes);
    }
    

    【讨论】:

    • 感谢 DuncG。有效。但我仍然不清楚为什么 InputStream 不起作用。我将它转换为字节数组。使用了字节数组。但是让 InputStream 内容丢失或指向 EOF。我不明白这里发生了什么。
    • 在这种情况下 getInputStream 返回相同的流,而不是重复http下载的新调用。通常 InputStreams 只能被使用一次,因此它被完全读取以获取字节数组,输入流状态现在位于文件末尾位置 - 因此读取下一个字节返回 -1。
    • 无法重置 InputStream 中的指针。因此 InputStream 将处于指向 EOF 的状态。明白了。谢谢。
    • 依赖于InputStream实现类。请参阅InputStream.reset()mark/markSupported。例如,new ByteArrayInputStream(bytes) 是一个 InputStream,可以像 new 一样重复使用,因为它支持 reset(),而 FileInputStream 不允许重置 - 你必须再次打开文件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-08
    • 2023-03-15
    • 1970-01-01
    • 2013-01-17
    • 1970-01-01
    • 2015-04-09
    相关资源
    最近更新 更多