Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 图像IO奇怪行为重置输入流_Java_Image_Io_Bufferedimage - Fatal编程技术网

Java 图像IO奇怪行为重置输入流

Java 图像IO奇怪行为重置输入流,java,image,io,bufferedimage,Java,Image,Io,Bufferedimage,我看到ImageIO.read()方法有一个奇怪的行为 我将InputStream传递给这个方法,当我第二次尝试读取它时,它无法读取并返回null 我试图上传图像到亚马逊S3,我想创建3个版本的图像。原稿和2个缩略图。我的问题是,当我想要创建2个缩略图时,我需要使用ImageIO.read()读取InputStream。如果我对相同的InputStream运行此方法2,则第二次读取时会得到null 我可以通过只读取一个并将相同的BuffereImage传递给scaling方法来避免这个问题。但是

我看到ImageIO.read()方法有一个奇怪的行为

我将InputStream传递给这个方法,当我第二次尝试读取它时,它无法读取并返回null

我试图上传图像到亚马逊S3,我想创建3个版本的图像。原稿和2个缩略图。我的问题是,当我想要创建2个缩略图时,我需要使用ImageIO.read()读取InputStream。如果我对相同的InputStream运行此方法2,则第二次读取时会得到null

我可以通过只读取一个并将相同的BuffereImage传递给scaling方法来避免这个问题。但是,我仍然需要我的方法获得的InputStream传递给其他版本的AmazonS3服务,以便上传原始文件

所以我的问题是,在ImageIO第一次读取输入流之后,有人知道它会发生什么吗

下面是代码示例

public String uploadImage(InputStream stream, String filePath, String fileName, String fileExtension) {
    try {

        String originalKey = filePath + fileName + "." + fileExtension;
        String smallThumbKey = filePath + fileName + ImageConst.Path.SMALL_THUMB + "." + fileExtension;
        String largetThumbKey = filePath + fileName + ImageConst.Path.LARGE_THUMB + "." + fileExtension;

        BufferedImage image = ImageIO.read(stream); 
        InputStream smallThumb = createSmallThumb(image, fileExtension);
        InputStream largeThumb = createLargeThumb(image, fileExtension);

        uploadFileToS3(originalKey, stream);
        uploadFileToS3(smallThumbKey, smallThumb);
        uploadFileToS3(largetThumbKey, largeThumb);

        return originalKey;

    } catch (IOException ex) {
        Logger.getLogger(ManageUser.class.getName()).log(Level.SEVERE, null, ex);
    }
    return null;
}

我想,您可以将原始输入流包装在一个文件中,并使用它保存流中的起始位置,然后返回到它


完整回答您的问题:每个流都按顺序读取(通常有某种内部指针指向当前位置)。在第一次
ImageIO.read()
之后,流一直被读取到其结束,因此,任何进一步的读取操作都不会返回任何数据(通常-1表示流的结束)。使用mark()可以保存某个位置,然后使用reset()返回到该位置。

我想,您可以将原始输入流包装成一个,并使用保存流中的起始位置,然后返回到该位置


完整回答您的问题:每个流都按顺序读取(通常有某种内部指针指向当前位置)。在第一次
ImageIO.read()
之后,流一直被读取到其结束,因此,任何进一步的读取操作都不会返回任何数据(通常-1表示流的结束)。使用mark()可以保存某个位置,然后使用reset()返回到该位置。

ImageIO.read将读取到输入流的末尾。这意味着没有数据可以读取,这就是为什么当您尝试从中读取更多数据时,会出现null

如果要重用输入流,必须对其调用reset();但只有在底层InputStream实现支持重置时,这才有效,请参见InputStream的markSupported()

这是一个简单但幼稚的解决办法

请记住,您已经将图像读入内存,因此您实际上不需要这样做。这有点笨拙,但您可以将其写入ByteArrayInputStream,然后在此基础上构建一个新的ByteArrayInputStream


如果我这样做的话,我可能会先把它读入一个字节数组。请查看Commons IOUtils.read()以了解这一点。然后我将根据需要构建一个新的ByteArrayInputStream和reset(),因为它肯定支持标记。

ImageIO.read将读取到输入流的末尾。这意味着没有数据可以读取,这就是为什么当您尝试从中读取更多数据时,会出现null

如果要重用输入流,必须对其调用reset();但只有在底层InputStream实现支持重置时,这才有效,请参见InputStream的markSupported()

这是一个简单但幼稚的解决办法

请记住,您已经将图像读入内存,因此您实际上不需要这样做。这有点笨拙,但您可以将其写入ByteArrayInputStream,然后在此基础上构建一个新的ByteArrayInputStream

如果我这样做的话,我可能会先把它读入一个字节数组。请查看Commons IOUtils.read()以了解这一点。然后,我将根据需要构建一个新的ByteArrayInputStream和reset(),因为它肯定支持标记。

+1我还建议使用“markSupported()”检查原始输入流是否支持标记,并且仅当原始输入流不支持标记时才使用缓冲流。+1我还建议使用“markSupported()”检查原始输入流是否支持标记并仅在原始输入流不支持时使用缓冲流。