总会有奇奇怪怪的需求,这不就来了一个,本来是内部的访问,非得给一个HTTP方式返回一个zip流来,只能去解析一下了,直接用java读取流里面的CSV文件就好了,对这块不太熟,网上找了点代码,看了大致了解了一下写了个demo出来,记录一下,免得以后再遇到不好找。
//从HTTP返回conn中直接获取zip文件里的具体CSV数据
private static ListgetListFromZipStream(HttpURLConnection conn) throws IOException {
BufferedInputStream bis = null;
ZipInputStream zin = null;
try {
//获取网络输入流
bis = new BufferedInputStream(conn.getInputStream());
zin = new ZipInputStream(bis);
Listlist = new ArrayList<>();
//这块是设置文件读取位置
while ((zin.getNextEntry()) != null) {
CsvReader csvReader = new CsvReader(zin, Charset.forName("gbk"));
csvReader.readHeaders();
while (csvReader.readRecord()) {
//第一个单号
String outerOrderIdStr = csvReader.get(0);
list.add(withdrawRecord);
}
}
return list;
} catch (Exception e) {
LogTypeEnum.EXCEPTION.error(e, "处理返回的流异常");
} finally {
if (bis != null) {
bis.close();
}
if (zin != null) {
zin.close();
}
}
return null;
}
里面有些代码我手动改了一下,要是出现异常问题自己处理一下就好了,这个是直接读取数据的,当然想直接输出CSV文件也很简单了,定义outputstream输出就好了,代码如下:
/**
将http返回来的zip流直接读取其中的csv文件并下载到本地
* @param conn
* @throws IOException
*/
private static void downloadFileFromZipStream(HttpURLConnection conn) throws IOException {
BufferedInputStream bis = null;
ZipInputStream zin = null;
int len;
byte[] buf = new byte[1024];
//注意创建文件夹问题,我这没有创建,自己手动再本地创建好文件夹
FileOutputStream fos = new FileOutputStream("D:\\zipTest\\folder\\订单流水表.csv");
try {
//获取网络输入流
bis = new BufferedInputStream(conn.getInputStream());
zin = new ZipInputStream(bis);
while ((zin.getNextEntry()) != null) {
while ((len = zin.read(buf)) != -1) {
fos.write(buf, 0, len);
}
}
// 关流顺序,先打开的后关闭
return ;
} catch (Exception e) {
} finally {
if (bis != null) {
bis.close();
}
if (zin != null) {
zin.close();
}
fos.close();
}
return ;
}
下面附上一个本地读取zip文件再输出的demo:
public static void main(String[] args) {
try {
//自己房放好一个zip文件的路径地址
String zipFilePath = "D:\\zip\\11.zip";
//输出文件路径地址
String destDirPath = "D:\\压缩文件\\test";
ZipFile zipFile = new ZipFile(new File(zipFilePath));
//处理zip文件使用
Enumeration entries = zipFile.entries();
InputStream is;
while (entries.hasMoreElements()) {
ZipEntry entry = (ZipEntry) entries.nextElement();
// 如果是文件,就先创建一个文件,然后用io流把内容copy过去
File targetFile = new File(destDirPath + "/" + entry.getName());
// 保证这个文件的父文件夹必须要存在
if (!targetFile.getParentFile().exists()) {
targetFile.getParentFile().mkdirs();
}
is = zipFile.getInputStream(entry);
FileOutputStream fos = new FileOutputStream(targetFile);
int len;
byte[] buf = new byte[1024];
while ((len = is.read(buf)) != -1) {
fos.write(buf, 0, len);
}
// 关流顺序,先打开的后关闭
fos.close();
is.close();
}
//获取到了所有的流
} catch (IOException e) {
} finally {
}
}
记忆一下,免得下次又懵逼,代码都可以跑通的,有些小问题是我拷贝到notepad脱敏改的可能:
参考了几篇文章:
https://blog.csdn.net/qq_34474324/article/details/97369763
http://blog.sina.com.cn/s/blog_b31d573d0101htil.html
https://www.jianshu.com/p/f891b135da88