diff --git a/pom.xml b/pom.xml index 25edbac..b84065c 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ yexuejc-base 1.5.0-jre8 - ${project.artifactId} + yexuejc-base https://github.com/yexuejc/yexuejc-base Common toolkits based on JDK8 packaging @@ -40,7 +40,7 @@ https://nexus.yexuejc.top/repository/ - http://maven.aliyun.com/nexus/content/groups/public + https://maven.aliyun.com/repository/public https://jitpack.io 0.11.5 true @@ -51,6 +51,7 @@ 1.70 31.1-jre 5.2.2 + 2.13.2 UTF-8 UTF-8 @@ -111,6 +112,12 @@ poi-ooxml ${apache-poi.version} + + com.fasterxml.jackson.dataformat + jackson-dataformat-csv + ${jackson.version} + + org.junit.jupiter junit-jupiter-api @@ -196,12 +203,12 @@ - yexuejc-nexus-public + yexuejc-maven yexuejc-nexus-public ${repos.yexuejc.url}maven-public/ - aliyun-nexus-public + aliyun-maven aliyun-nexus-public ${repos.aliyun.url} diff --git a/src/main/java/com/yexuejc/base/util/FileUtil.java b/src/main/java/com/yexuejc/base/util/FileUtil.java index d45613e..956f528 100644 --- a/src/main/java/com/yexuejc/base/util/FileUtil.java +++ b/src/main/java/com/yexuejc/base/util/FileUtil.java @@ -1,8 +1,14 @@ package com.yexuejc.base.util; +import com.fasterxml.jackson.databind.MappingIterator; +import com.fasterxml.jackson.dataformat.csv.CsvMapper; +import com.fasterxml.jackson.dataformat.csv.CsvSchema; +import com.google.common.io.ByteStreams; +import com.google.common.io.CharStreams; import com.yexuejc.base.annotation.CsvHeader; import com.yexuejc.base.pojo.ReadFileBean; import io.jsonwebtoken.lang.Assert; +import org.apache.commons.io.IOUtils; import java.io.*; import java.math.BigInteger; @@ -14,9 +20,10 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Base64; -import java.util.Collection; import java.util.List; +import java.util.Scanner; import java.util.logging.Logger; +import java.util.stream.Collectors; import java.util.zip.CRC32; /** @@ -418,19 +425,65 @@ public class FileUtil { /** * 字符串(csv格式)转 对象 * - * @param datas 转换的字符串 如 - *

------------

- *

id,name,age

- *

1,zhangsan,18

- *

2,lisi,20

- *

------------

- * @param cls 需要转换的对象,含有id,name,age字段 + * @param data 转换的字符串 如 + *

------------

+ *

id,name,age

+ *

1,zhangsan,18

+ *

2,lisi,20

+ *

------------

+ * @param cls 需要转换的对象,含有id,name,age字段 + * @param delimiter 分隔符 * @param * @return */ - public static List readCsv(String datas, Class cls) { + public static List readCsv(String data, Class cls, char delimiter) throws IOException { + CsvMapper csvMapper = new CsvMapper(); + CsvSchema csvSchema = CsvSchema.emptySchema().withHeader().withColumnSeparator(delimiter); + MappingIterator orderLines = csvMapper.readerFor(cls).with(csvSchema).readValues(data); + return orderLines.readAll(); + } - return null; + /** + * 读取csv文件 + * + * @param csvFilePath 文件地址 + * @param cls 读取转化的对象 + * @param hasHeader 是否存在header + * @param delimiter 分隔符.默认【,】 + * @param + * @return + */ + public static List readCsv(final String csvFilePath, Class cls, boolean hasHeader, char delimiter) { + if (!isFileExist(csvFilePath)) { + throw new RuntimeException(String.format("解析用的csv:\u0020[%s] 文件不存在。", csvFilePath)); + } + if (StrUtil.isEmpty(delimiter)) { + delimiter = ','; + } + try { + File csvFile = new File(csvFilePath); + CsvMapper csvMapper = new CsvMapper(); + CsvSchema csvSchema = csvMapper.typedSchemaFor(cls).withStrictHeaders(hasHeader).withColumnSeparator(delimiter).withComments(); + MappingIterator recordIterator = csvMapper.readerWithTypedSchemaFor(cls).with(csvSchema).readValues(csvFile); + return recordIterator.readAll(); + } catch (IOException e) { + throw new RuntimeException("[" + csvFilePath + "] 文件解析失败。", e); + } + } + + /** + * 判断文件是否存在 + * + * @param filePath + * @return + */ + public static boolean isFileExist(String filePath) { + if (StrUtil.isEmpty(filePath)) { + return false; + } + + File file = new File(filePath); + return file.exists() && !file.isDirectory(); } /** @@ -458,7 +511,7 @@ public class FileUtil { if (path.contains(TYPE_CSV)) { //csv文件处理 datas.add(0, getCsvHeader(readCls)); - List dataList = readCsv(String.join("\n", datas), readCls); + List dataList = readCsv(String.join("\n", datas), readCls, ','); readFileBean.setDatas(dataList); } } catch (FileNotFoundException e) { @@ -501,6 +554,193 @@ public class FileUtil { } + /** + * 提供读取IO流方法合集 + *

读取速度快慢顺序:

+ * 1. {@link #read4Buffer(InputStream, Charset)}
+ * 2. {@link #read4IOUtilsCopy(InputStream, Charset)}
+ * 3. {@link #read4ByteStreams(InputStream, Charset)}
+ * 4. {@link #read4Byte(InputStream, Charset)}
+ * 5. {@link #read4StringBuilder(InputStream, Charset)}
+ * 6. {@link #read4BufferedReaderParallel(InputStream, Charset, String)}
+ * 7. {@link #read4BufferedReader(InputStream, Charset, String)}
+ * 8. {@link #read4ScannerA(InputStream)}
+ * 9. {@link #read4BufferIO(InputStream, Charset)}
+ * 10. {@link #read4IOUtils(InputStream, Charset)}
+ * 11. {@link #read4ScannerZ(InputStream)}
+ * 12. {@link #read4CharStreams(InputStream, Charset)}
+ */ + public static class FileInput { + /** + * 读取IO流内容:byte方式 + * + * @param inputStream + * @param charset 编码:默认 {@link Charset#defaultCharset()} + * @return + * @throws IOException + */ + public static String read4Byte(InputStream inputStream, Charset charset) throws IOException { + byte[] bytes = new byte[inputStream.available()]; + inputStream.read(bytes); + return new String(bytes, charset == null ? Charset.defaultCharset() : charset); + } + + /** + * 读取IO流内容:BufferedReader方式 + * + * @param inputStream + * @param charset 编码:默认跟随系统 {@link Charset#defaultCharset()} + * @param lineSeparator 换行方式:默认跟随系统 {@link System#lineSeparator()} + * @return + */ + public static String read4BufferedReader(InputStream inputStream, Charset charset, String lineSeparator) { + return new BufferedReader( + new InputStreamReader(inputStream, charset == null ? Charset.defaultCharset() : charset) + ).lines().collect(Collectors.joining(lineSeparator == null ? System.lineSeparator() : lineSeparator)); + } + + /** + * 读取IO流内容:BufferedReader 并行方式 + * + * @param inputStream + * @param charset 编码:默认跟随系统 {@link Charset#defaultCharset()} + * @param lineSeparator 换行方式:默认跟随系统 {@link System#lineSeparator()} + * @return + */ + public static String read4BufferedReaderParallel(InputStream inputStream, Charset charset, String lineSeparator) { + return new BufferedReader( + new InputStreamReader(inputStream, charset == null ? Charset.defaultCharset() : charset) + ).lines().parallel() + .collect(Collectors.joining(lineSeparator == null ? System.lineSeparator() : lineSeparator)); + } + + + /** + * 读取IO流内容:Scanner A方式 + * + * @param inputStream + * @return + */ + public static String read4ScannerA(InputStream inputStream) { + Scanner s = new Scanner(inputStream).useDelimiter("\\A"); + String str = s.hasNext() ? s.next() : ""; + return str; + } + + /** + * 读取IO流内容:Scanner Z方式 + * + * @param inputStream + * @return + */ + public static String read4ScannerZ(InputStream inputStream) { + return new Scanner(inputStream).useDelimiter("\\Z").next(); + } + + + /** + * 读取IO流内容:StringBuilder方式 + * + * @param inputStream + * @param charset 编码:默认跟随系统 {@link Charset#defaultCharset()} + * @return + */ + public static String read4StringBuilder(InputStream inputStream, Charset charset) throws IOException { + StringBuilder sb = new StringBuilder(); + String line; + BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, charset == null ? Charset.defaultCharset() : charset)); + while ((line = br.readLine()) != null) { + sb.append(line); + } + return sb.toString(); + } + + /** + * 读取IO流内容:ByteArrayOutputStream方式 + * + * @param inputStream + * @param charset 编码:默认跟随系统 {@link Charset#defaultCharset()} + * @return + */ + public static String read4Buffer(InputStream inputStream, Charset charset) throws IOException { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int length; + while ((length = inputStream.read(buffer)) != -1) { + result.write(buffer, 0, length); + } + return result.toString(charset == null ? Charset.defaultCharset().name() : charset.name()); + } + + /** + * 读取IO流内容:BufferedInputStream+ByteArrayOutputStream方式 + * + * @param inputStream + * @param charset 编码:默认跟随系统 {@link Charset#defaultCharset()} + * @return + */ + public static String read4BufferIO(InputStream inputStream, Charset charset) throws IOException { + BufferedInputStream bis = new BufferedInputStream(inputStream); + ByteArrayOutputStream buf = new ByteArrayOutputStream(); + int result = bis.read(); + while (result != -1) { + buf.write((byte) result); + result = bis.read(); + } + return buf.toString(charset == null ? Charset.defaultCharset().name() : charset.name()); + } + + /** + * 读取IO流内容: 依赖于commons-io:commons-io {@link IOUtils#copy(Reader, OutputStream, Charset)} + * + * @param inputStream + * @param charset 编码:默认跟随系统 {@link Charset#defaultCharset()} + * @return + * @throws IOException + */ + public static String read4IOUtilsCopy(InputStream inputStream, Charset charset) throws IOException { + StringWriter writer = new StringWriter(); + IOUtils.copy(inputStream, writer, charset == null ? Charset.defaultCharset() : charset); + return writer.toString(); + } + + /** + * 读取IO流内容: 依赖于commons-io:commons-io {@link IOUtils#toString(InputStream, Charset)} + * + * @param inputStream + * @param charset 编码:默认跟随系统 {@link Charset#defaultCharset()} + * @return + * @throws IOException + */ + public static String read4IOUtils(InputStream inputStream, Charset charset) throws IOException { + return IOUtils.toString(inputStream, charset == null ? Charset.defaultCharset() : charset); + } + + /** + * 读取IO流内容: 依赖于com.google.guava:guava {@link CharStreams#toString(Readable)} + * + * @param inputStream + * @param charset 编码:默认跟随系统 {@link Charset#defaultCharset()} + * @return + * @throws IOException + */ + public static String read4CharStreams(InputStream inputStream, Charset charset) throws IOException { + return CharStreams.toString(new InputStreamReader(inputStream, charset == null ? Charset.defaultCharset() : charset)); + } + + /** + * 读取IO流内容: 依赖于com.google.guava:guava {@link ByteStreams#toByteArray(InputStream)} + * + * @param inputStream + * @param charset 编码:默认跟随系统 {@link Charset#defaultCharset()} + * @return + * @throws IOException + */ + public static String read4ByteStreams(InputStream inputStream, Charset charset) throws IOException { + return new String(ByteStreams.toByteArray(inputStream), charset == null ? Charset.defaultCharset() : charset); + } + } + /*public static void main(String[] args) { long size = FileUtil.size(new File("E:\\OS\\deepin-15.6-amd64\\DeepinCloudPrintServerInstaller_1.0.0.1.exe")); System.out.println(size);