使用背景
最近项目中有接收其他部门数据的需求,之前一直使用的mns,但这次的数据量较大,因此选择通过mns传递oss文件路径,到oss上读取具体内容,文件采用的csv,下面上代码。
1、pom文件加入依赖
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<version>1.4</version>
</dependency>
2、oss下载文件并读取csv文件
@Service
@Slf4j
public class OssServiceImpl implements IOssService {
private String endPoint = "xxxxxxxxxxxxxxxxx";
private String accessKeyId = "xxxxxxxxxxxxxxxxx";
private String accessKeySecret = "xxxxxxxxxxxxxxxxx";
private String bucketName = "xxxxxxxxxxxxxxxxx";
@Override
public void consumeTagBiMns(Mns mns) {
if (Objects.isNull(mns)) {
return;
}
//获取文件目录
String filePath = mns.getFilePath();
if(StringUtils.isBlank(filePath)){
log.error("filePath为空!");
return;
}
//创建连接
OSS ossClient = getOssClient();
//获取文件夹下唯一文件名称
String objectName = getObjectName(filePath, ossClient);
if(StringUtils.isBlank(objectName)){
log.error("获取oss文件名称失败!");
return;
}
// 获取文件信息 ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。
OSSObject ossObject = ossClient.getObject(bucketName, objectName);
// 使用缓冲流读取 设置编码格式
try(BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent(),"utf-8"))){
// 读取csv文件
CSVParser parser = getCsvRecords(reader);
//遍历每一行数据
List<CSVRecord> csvRecords = parser.getRecords();
//第一行数据是字段名称 跳过
if(CollectionUtils.isEmpty(csvRecords)){
return;
}
for (int i = 1 ; i < csvRecords.size();i++){
CSVRecord record = csvRecords.get(i);
System.out.println(record);
}
// 关闭OSSClient。
ossClient.shutdown();
// 数据读取完成后,获取的流必须关闭,否则会造成连接泄漏,导致请求无连接可用,程序无法正常工作。
} catch (Exception e) {
throw new RuntimeException();
}
}
private CSVParser getCsvRecords(BufferedReader reader) throws IOException {
return CSVFormat.DEFAULT.withHeader("字段名称1","字段名称2").parse(reader);
}
private String getObjectName(String filePath, OSS ossClient) {
try{
// 构造ListObjectsRequest请求
ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName);
//Delimiter 设置为 “/” 时,罗列该文件夹下的文件
listObjectsRequest.setDelimiter("/");
//Prefix 设为某个文件夹名,罗列以此 Prefix 开头的文件
listObjectsRequest.setPrefix(filePath);
//列举文件夹下所有文件
ObjectListing listing = ossClient.listObjects(listObjectsRequest);
if(CollectionUtils.isEmpty(listing.getObjectSummaries())){
log.error("文件夹为空:" + filePath);
return null;
}
//打印所有文件
for (OSSObjectSummary os :listing.getObjectSummaries()) {
log.info("文件:--{}",os.getKey());
//结尾为“csv”即文件全路径
if(os.getKey().endsWith("csv")){
return os.getKey();
}
}
}catch (OSSException e) {
// OSS在查找不到某对象时,会抛出ErrorCode为“NoSuchKey”的OSSException,而不是返回null
if (e.getErrorCode().contains("NoSuchKey")) {
log.error("找不到文件夹:" + filePath,e);
} else {
log.error("OSS连接失败!,emsg:{}",e);
}
return null;
}
return null;
}
private OSS getOssClient() {
// 创建ClientConfiguration实例
ClientConfiguration conf = new ClientConfiguration();
// 设置OSSClient使用的最大连接数,默认200
conf.setMaxConnections(200);
// 设置请求超时时间,默认10秒
conf.setSocketTimeout(10000);
// 设置失败请求重试次数,默认3次
conf.setMaxErrorRetry(3);
return new OSSClient(endPoint, accessKeyId, accessKeySecret, conf);
}
}