我们如何读取或使用输出流的内容 [关闭]

Posted

技术标签:

【中文标题】我们如何读取或使用输出流的内容 [关闭]【英文标题】:How can we read or use the contents of outputstream [closed] 【发布时间】:2013-08-04 11:23:34 【问题描述】:

我们如何读取或使用输出流的内容。 就我而言,我使用的是具有签名的方法。

public static OutputStream decryptAsStream(InputStream inputStream, 字符串加密密钥)

这个方法返回OutputStream。我想将 OutputStream 转换为字符串。 是否可以将 java.io.OutputStream 的输出通过管道传输到 Java 中的字符串?

【问题讨论】:

你不会从输出流中读取 - 你会写入输出流:docs.oracle.com/javase/7/docs/api/java/io/… 【参考方案1】:

我们如何读取或使用输出流的内容。

一般来说你不能。 OutputStream 是您写入字节的对象。通用 API 不提供任何方法来取回字节。

有特定种类的输出流可以让您取回字节。例如:

ByteArrayOutputStream 有一个获取字节数组内容的方法。 PipeOutputStream 具有对应的 PipeInputStream,您可以从中读取。 如果您使用FileOutputStream 写入文件,则通常可以打开FileInputStream 来读取文件内容...只要您知道文件路径名。

看着那个方法,我觉得方法签名对于您正在尝试做的事情是错误。如果目的是为流提供加密器,则该方法应返回InputStream。如果目的是将加密数据写入某处,则该方法应返回void 并采用一个额外的参数,即该方法应写入的OutputStream。 (然后调用者可以使用OutputStream 子类来捕获加密数据......如果这是需要的话。)

另一个“有效”的替代方法是更改​​方法的签名以使返回类型为ByteArrayOutputStream(或文件名)。但这不是一个好的解决方案,因为它剥夺了调用者决定加密输出应该发送到哪里的能力。


更新

关于你的解决方案

    OutputStream os = AESHelper.decryptAsStream(sourceFile, encryptionKey);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    baos = (ByteArrayOutputStream) os;  
    byte[] imageBytes = baos.toByteArray();  
    response.setContentType("image/jpeg");  
    response.setContentLength(imageBytes.length);  
    OutputStream outs = response.getOutputStream();  
    outs.write(imageBytes);

这可行,但代码很糟糕:

如果 AESHelper.decryptAsStream 是您编写的方法(看起来确实如此!),那么您应该将其声明为返回 ByteArrayOutputStream

如果它已经声明为返回ByteArrayOutputStream,则应将其直接分配给baos

无论哪种方式,您都不应该将 baos 初始化为新创建的 ByteArrayOutputStream 实例,该实例会立即被丢弃。

另外值得注意的是 Content-Type 不正确。如果您将该响应发送到浏览器,它会尝试将加密数据解释为图像......并且失败。从理论上讲,您可以设置一个 Content-Encoding 标头......但没有一个可以工作。所以最好的解决方案是将 Content-Type 发送为“application/octet-stream”。

【讨论】:

【参考方案2】:

您可以执行以下操作:

  OutputStream output = new OutputStream()
    
        private StringBuilder string = new StringBuilder();
        @Override
        public void write(int x) throws IOException 
            this.string.append((char) x );
        

        public String toString()
            return this.string.toString();
        
    ;

【讨论】:

这是测试写入 OutputStream 内容的绝佳解决方案。谢谢! 谢谢你,我有调试日志的解决方案!【参考方案3】:

主要你可以使用outputstreams来发送文件内容,就像@The New Idiot提到的那样。 .pdf 文件、zip 文件、图像文件等

在这种情况下,获取 servlet 的输出流并写入内容

OutputStream outStream = response.getOutputStream();
FileInputSteram fis = new FileInputStream(new File("abc.pdf));
byte[] buf = new byte[4096];
int len = -1;
while ((len = fis.read(buf)) != -1) 
    outStream .write(buf, 0, len);

response.setContentType("application/octect");(if type is binary) else 
response.setContentType("text/html");
outStream .flush();
outStream.close();

【讨论】:

【参考方案4】:

如果您从response 获得OutputStream,您可以将OutputStream 的内容写入将发送回浏览器的响应。示例代码:

OutputStream outStream = response.getOutputStream();
response..setHeader("Content-Disposition", "attachment; filename=datafile.xls");
response.setContentType("application/vnd.ms-excel");
byte[] buf = new byte[4096];
int len = -1;
while ((len = inStream.read(buf)) != -1) 
    outStream.write(buf, 0, len);


outStream.flush();
outStream.close();

阅读:Content-Disposition:What are the differences between “inline” and “attachment”?


在您的情况下,方法定义是:

public static OutputStream decryptAsStream(InputStream inputStream,
                                            String encryptionKey)

所以你可以从那个方法中得到OutputStream

OutputStream os = ClassName.decryptAsStream(inputStream,encryptionKey);

然后使用os

【讨论】:

以上是关于我们如何读取或使用输出流的内容 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

javaIO流之字节到字符流的转换流

字节流与字符流的区别详解

字节流与字符流的区别详解

Java IO流中先关闭输出流还是先关闭输入流?为啥?

字节流与字符流的区别详解

java中输出流不关闭为啥不能写入