闲暇之余,想撸一些代码,刚好想到appcheck扫描会扫描出项目中依赖的jar的Component、Vision、License信息,最终可以导出.csv格式文件,而.csv是免费的,所以写了个demo读取csv。
首先:我们创造一个CsvReader工厂类,来生产每一个CsvReader对象。代码简洁,就直接上代码了。
附上依赖:
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>4.1</version>
</dependency>
package com.reader.csv.csv;
import com.opencsv.CSVReader;
import com.opencsv.CSVReaderBuilder;
import com.opencsv.RFC4180Parser;
import com.opencsv.RFC4180ParserBuilder;
import com.reader.csv.util.IOUtils;
import com.reader.csv.util.UnicodeReader;
import java.io.*;
/**
* @author lucas 2019/6/20 9:42
* @version V1.0
*/
public class CsvReaderFactory {
private File file;
private String charSet;
private static final String DEFAULT_CHAR_SET = "utf-8";
private RFC4180Parser rfc4180Parser;
private CSVReaderBuilder csvReaderBuilder;
private FileInputStream fileInputStream;
private CSVReader csvReader;
public CsvReaderFactory(File file, String charSet){
this.file = file;
this.charSet = charSet;
}
public RFC4180Parser getRfc4180Parser(){
if (null == this.rfc4180Parser) {
this.rfc4180Parser = (new RFC4180ParserBuilder()).build();
}
return this.rfc4180Parser;
}
public static BufferedReader getReader(InputStream is, String charSet) {
return is == null ? null : new BufferedReader(new UnicodeReader(is, charSet));
}
private CSVReaderBuilder getCsvReaderBuilder(){
if (this.csvReaderBuilder == null) {
this.csvReaderBuilder = new CSVReaderBuilder(IOUtils.getReader(getFileInputStream(), this.charSet == null?DEFAULT_CHAR_SET:this.charSet));
}
return this.csvReaderBuilder;
}
public CSVReader getCsvReader(){
if (csvReader == null) {
this.csvReader = getCsvReaderBuilder().build();
}
return this.csvReader;
}
private FileInputStream getFileInputStream(){
try {
this.fileInputStream = new FileInputStream(this.file);
} catch (FileNotFoundException e) {
throw new RuntimeException("file not found error", e);
} catch (Exception e) {
throw new RuntimeException(e);
}
return this.fileInputStream;
}
public void close(){
try {
if (this.fileInputStream != null) {
this.fileInputStream.close();
}
if (this.csvReader != null) {
csvReader.close();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
我们既然有了CsvReader工厂类,生产CsvReader就只需要创造一个工厂类对象,就会生产一个CsvReader对象。但是这样无法保证每一个用工厂类的人会去调用close(),关闭InputStream和Reader,所以继续封装一层。
package com.reader.csv.csv;
import com.opencsv.CSVReader;
import java.io.File;
import java.util.List;
/**
* <p>CsvReaderOutput</p>
* @author lucas 2019/6/29 9:39
* @version V1.0
*/
public class CsvReaderOutput {
private List<String []> strings;
private File file;
private String charSet;
private CsvReaderFactory csvReaderFactory;
private CSVReader csvReader;
public static final String CSV_FORMAT = ".csv";
public CsvReaderOutput(File file, String charSet){
this.charSet = charSet;
this.file = file;
}
public List<String []> getStrings(){
try {
this.strings = getCsvReader().readAll();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
this.csvReaderFactory.close();
}
return this.strings;
}
private CsvReaderFactory getCsvReaderFactory(){
if (this.csvReaderFactory == null) {
this.csvReaderFactory = new CsvReaderFactory(this.file, this.charSet);
}
return this.csvReaderFactory;
}
private CSVReader getCsvReader(){
if (this.csvReader == null) {
this.csvReader = getCsvReaderFactory().getCsvReader();
}
return this.csvReader;
}
}
封装后可以直接获取到每一个csv文件的所有数据信息,放入List<String []>中,List对应行,String []对应每一列。
package com.reader.csv;
import com.reader.csv.csv.CsvReaderOutput;
import java.io.File;
import java.util.List;
/**
* @author lucas 2019/6/28 11:52
* @version V1.0
*/
public class CsvReaderTest {
public static void main(String[] args){
File[] list = new File("D:\\00csv").listFiles();
for (File file : list) {
if (file.isFile() && file.getName().endsWith(".csv")){
CsvReaderOutput csvReaderOutput = new CsvReaderOutput(file, "utf-8");
List<String[]> allLines = csvReaderOutput.getStrings();
for (String[] strings :allLines) {
System.out.println(strings[0]);
}
break;
}
}
}
}
用一个.csv格式文档测试一下,代码简洁可靠,更重要的是将close封装起来无需调用者自己去close(),避免了安全性问题。
当然,如果数据量非常大,这样的代码模式是不能满足的,需要自行扩展代码,利用缓存或边读边写的方式去进行。当然,这些代码也只是一个简单的思路。