業務場景:根據url拿到輸入流(url其實就是個下載鏈接),拿到輸入流後要做兩個操作:1.上傳阿里雲Oss 2.解析輸入流讀取每一行,轉換成實體類存數據庫
問題解析:輸入流在第一次被讀取使用之後,流的數據就消耗完了,所以想要重用的話,需要將流數據存入容器,再從容器取出數據構造流.(這裏好多同學容易誤解成:流使用完了,會被關閉,其實這裏打斷點發現的是流使用完不會被關閉,而是裏面的數據都被清空了,可以理解成水流,流走了就沒有了), 下面上代碼:
複製流(傳入原始流,返回數據容器):
/**
* 複製流
* @param inputStream
* @return
*/
private ByteArrayOutputStream copyStream(InputStream inputStream) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
byte[] buffer = new byte[4096];
int len;
while ((len = inputStream.read(buffer)) > -1) {
baos.write(buffer, 0, len);
}
baos.flush();
} catch (IOException e) {
log.error("複製流異常:" + e.getMessage());
}
return baos;
}
構造流對象,使用重複的流數據(構造了兩個流對象做不同的操作):
try {
entity.setPlatform_trace(platform_trace);
inputStream = getInputStreamByUrl(entity.getUrl());
//先複製流對象並返回,防止程序後面使用到流數據空了的流對象
ByteArrayOutputStream baos = copyStream(inputStream);
//構造同樣數據的不同流對象
InputStream inputStreamCopyOss = new ByteArrayInputStream(baos.toByteArray());
InputStream inputStreamCopyRead = new ByteArrayInputStream(baos.toByteArray());
//1.開啓新線程,保存阿里雲
executor.submit(() ->
uploadOss(entity, inputStreamCopyOss));
//2.保存數據庫
reader = new BufferedReader(new InputStreamReader(inputStreamCopyRead, "UTF-8"));
String str = null;
while (true) {
//每次讀一行
str = reader.readLine();
...
保存阿里雲:
/**
* 保存阿里雲
* @param entity
* @param inputStream
*/
private void uploadOss(BwDataListEntity entity, InputStream inputStream) {
String endpoint = OssConfig.getOssEndpoint();
String accessKeyId = OssConfig.getOssAccessKeyId();
String accessKeySecret = OssConfig.getOssAccessKeySecret();
String bucketName = OssConfig.getBucketName();
String objectName = "";
if (BaiWangConfig.getJxfp().equals(entity.getType())) {
//進項
objectName = getObjectName("input-invoice-file", entity.getPlatform_trace(), entity.getUrl());
} else {
//銷項
objectName = getObjectName("output-invoice-file", entity.getPlatform_trace(), entity.getUrl());
}
// 創建OSSClient實例
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
try {
// 上傳文件流
ossClient.putObject(bucketName, objectName, inputStream);
} catch (Exception e) {
log.error("阿里雲上傳文件失敗:" + e.getMessage());
} finally {
// 關閉OSSClient。
ossClient.shutdown();
}
}