如何消除S3ObjectInputStream未读完字节的HTTP连接中止警告?
解决S3未读完输入流的警告问题
问题原因
你虽然用了withRange(0,1)发起范围GET请求,但AWS SDK的S3ObjectInputStream在关闭时检测到仍有未读取的字节,就会触发这个警告——SDK认为这是异常情况,会中断HTTP连接,可能导致性能问题。
即使请求了小范围,只要流里的字节没被完全读取,就会触发该警告。比如你的getMimeType方法可能只读取了部分字节就返回,剩下的字节留在流里没处理。
解决方案
要消除警告,必须确保完全读取请求范围内的所有字节,或者主动排空输入流后再关闭。以下是两种可行的实现方式:
方式1:手动排空输入流
在获取完MIME类型后,主动读取流中剩余的所有字节,直到流结束:
public CheckMimeTypeResult isValidObjectInQuarantineBucket(String bucket, String key) { GetObjectRequest request = new GetObjectRequest(bucket, key) .withRange(0, 1); try (S3Object s3Object = s3client.getObject(request)) { String mimeType = getMimeType(s3Object); // 排空输入流,避免警告 InputStream inputStream = s3Object.getObjectContent(); byte[] buffer = new byte[1024]; while (inputStream.read(buffer) != -1) { // 无需处理读取到的字节,仅用于排空流 } CheckMimeTypeResult result = isSupportedMimeType(mimeType) ? checkMimeType(key, mimeType) : new CheckMimeTypeResult(false, false, mimeType); log.debug("isValidObjectInQuarantineBucket() - end: key = {}, result = {}", key, result); return result; } catch (Exception ex) { log.warn("Could not detect mime type for key {}. ex = {}", key, ex.getMessage(), ex); CheckMimeTypeResult result = new CheckMimeTypeResult(false, false, null); log.debug("isValidObjectInQuarantineBucket() - end: key = {}, result = {}", key, result); return result; } }
方式2:使用工具类快速排空
如果项目中引入了Apache Commons IO工具包,可以直接用IOUtils.consume()方法简化代码:
// 先导入工具类 import org.apache.commons.io.IOUtils; public CheckMimeTypeResult isValidObjectInQuarantineBucket(String bucket, String key) { GetObjectRequest request = new GetObjectRequest(bucket, key) .withRange(0, 1); try (S3Object s3Object = s3client.getObject(request)) { String mimeType = getMimeType(s3Object); // 用工具类排空流 IOUtils.consume(s3Object.getObjectContent()); CheckMimeTypeResult result = isSupportedMimeType(mimeType) ? checkMimeType(key, mimeType) : new CheckMimeTypeResult(false, false, mimeType); log.debug("isValidObjectInQuarantineBucket() - end: key = {}, result = {}", key, result); return result; } catch (Exception ex) { log.warn("Could not detect mime type for key {}. ex = {}", key, ex.getMessage(), ex); CheckMimeTypeResult result = new CheckMimeTypeResult(false, false, null); log.debug("isValidObjectInQuarantineBucket() - end: key = {}, result = {}", key, result); return result; } }
额外检查点
确认你的getMimeType方法没有提前关闭输入流,也没有只读取部分字节就停止——如果该方法已经读取了请求范围内的所有字节,那么就不需要额外排空流。但如果它只读取了部分内容(比如只读了第一个字节),就必须补充排空操作。
内容的提问来源于stack exchange,提问作者heh
相关产品推荐
相关产品推荐

