diff --git a/src/main/java/com/yexuejc/base/annotation/CsvHeader.java b/src/main/java/com/yexuejc/base/annotation/CsvHeader.java new file mode 100644 index 0000000..30ff72c --- /dev/null +++ b/src/main/java/com/yexuejc/base/annotation/CsvHeader.java @@ -0,0 +1,21 @@ +package com.yexuejc.base.annotation; + +import java.lang.annotation.*; + +/** + * 设置csv header + * + * @author MAXF-MAC + */ +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Inherited +public @interface CsvHeader { + + /** + * 在类头上设置csv格式的header + * @return + */ + String header(); +} diff --git a/src/main/java/com/yexuejc/base/util/ToUeProperty.java b/src/main/java/com/yexuejc/base/annotation/ToUeProperty.java similarity index 95% rename from src/main/java/com/yexuejc/base/util/ToUeProperty.java rename to src/main/java/com/yexuejc/base/annotation/ToUeProperty.java index 530c9f1..c75e530 100644 --- a/src/main/java/com/yexuejc/base/util/ToUeProperty.java +++ b/src/main/java/com/yexuejc/base/annotation/ToUeProperty.java @@ -1,4 +1,6 @@ -package com.yexuejc.base.util; +package com.yexuejc.base.annotation; + +import com.yexuejc.base.util.ObjUtil; import java.lang.annotation.*; diff --git a/src/main/java/com/yexuejc/base/pojo/ReadFileBean.java b/src/main/java/com/yexuejc/base/pojo/ReadFileBean.java new file mode 100644 index 0000000..314a96c --- /dev/null +++ b/src/main/java/com/yexuejc/base/pojo/ReadFileBean.java @@ -0,0 +1,85 @@ +package com.yexuejc.base.pojo; + +import java.util.List; + +/** + * @author maxf + * @class-name ReadFileBean + * @description 分段读取大文件 + * @date 2022/5/16 21:53 + */ +public class ReadFileBean { + /** + * 开始行数 + */ + private int startRowNum; + /** + * 结束行数 + */ + private int endRowNum; + + /** + * 每次读取的行数 + */ + private int readRowNum; + /** + * 开始行到结束行的数据 + */ + private List datas; + /** + * 文件指针位置,默认0,开始位置 + */ + private long pointer = 0; + /** + * 文件的length + */ + private long fileLength; + + + public ReadFileBean(int readRow) { + this.readRowNum = readRow; + this.startRowNum = 1; + this.endRowNum = 0; + } + + public int getReadRowNum() { + return readRowNum; + } + + public int getStartRowNum() { + return startRowNum; + } + + public int getEndRowNum() { + return endRowNum; + } + + public List getDatas() { + return datas; + } + + public ReadFileBean setDatas(List datas) { + this.datas = datas; + this.startRowNum = this.endRowNum + 1; + this.endRowNum += this.readRowNum; + return this; + } + + public long getPointer() { + return pointer; + } + + public ReadFileBean setPointer(long pointer) { + this.pointer = pointer; + return this; + } + + public long getFileLength() { + return fileLength; + } + + public ReadFileBean setFileLength(long fileLength) { + this.fileLength = fileLength; + return this; + } +} diff --git a/src/main/java/com/yexuejc/base/util/FileUtil.java b/src/main/java/com/yexuejc/base/util/FileUtil.java index 2c99a1a..d45613e 100644 --- a/src/main/java/com/yexuejc/base/util/FileUtil.java +++ b/src/main/java/com/yexuejc/base/util/FileUtil.java @@ -1,12 +1,21 @@ package com.yexuejc.base.util; +import com.yexuejc.base.annotation.CsvHeader; +import com.yexuejc.base.pojo.ReadFileBean; +import io.jsonwebtoken.lang.Assert; + import java.io.*; import java.math.BigInteger; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; 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.logging.Logger; import java.util.zip.CRC32; @@ -25,6 +34,7 @@ public class FileUtil { } private static final String TYPE_TAR_GZ = ".tar.gz"; + private static final String TYPE_CSV = ".csv"; private static final String TAR_GZ = "tar.gz"; /** @@ -49,7 +59,7 @@ public class FileUtil { } /** - * 判断文件是否存在 + * 判断文件是否存在,不存在就创建一个空的 * * @param file */ @@ -405,6 +415,92 @@ public class FileUtil { return 0; } + /** + * 字符串(csv格式)转 对象 + * + * @param datas 转换的字符串 如 + *

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

+ *

id,name,age

+ *

1,zhangsan,18

+ *

2,lisi,20

+ *

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

+ * @param cls 需要转换的对象,含有id,name,age字段 + * @param + * @return + */ + public static List readCsv(String datas, Class cls) { + + return null; + } + + /** + * 分段读取大文件 + * + * @param path 文件路径 + * @param readFileBean 分段每次读取的bean 初始值需要设置每次读取的行数 + * @param 读取结果类型bean + * @return + */ + public ReadFileBean readBigFile(String path, ReadFileBean readFileBean, Class readCls) { + File file = new File(path); + judeFileExists(file); + try { + RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r"); + randomAccessFile.seek(readFileBean.getPointer()); + readFileBean.setFileLength(randomAccessFile.length()); + List datas = new ArrayList<>(); + for (int i = 0; i < readFileBean.getReadRowNum(); i++) { + String s = randomAccessFile.readLine(); + datas.add(charsetDecode(s, StandardCharsets.UTF_8)); + readFileBean.setPointer(randomAccessFile.getFilePointer()); + } + randomAccessFile.close(); + if (path.contains(TYPE_CSV)) { + //csv文件处理 + datas.add(0, getCsvHeader(readCls)); + List dataList = readCsv(String.join("\n", datas), readCls); + readFileBean.setDatas(dataList); + } + } catch (FileNotFoundException e) { + logger.severe("file exists." + e.getMessage()); + } catch (IOException e) { + logger.severe("read file error." + e.getMessage()); + } + return readFileBean; + } + + /** + * 获取csv的header,使用注解{@link CsvHeader} + * + * @param cls + * @param + * @return + */ + public static String getCsvHeader(Class cls) { + CsvHeader annotation = cls.getAnnotation(CsvHeader.class); + Assert.notNull(annotation, cls.toString() + "类上需要添加注解@CsvHeader,并指定header。"); + String header = annotation.header(); + Assert.notNull(header, cls.toString() + "类上需要添加注解@CsvHeader,并指定header。"); + return header; + } + + /** + * 把字符串data按照指定编码解码 + * + * @param data 解码字符串 + * @param charset 字符编码 + * @return + */ + public static String charsetDecode(String data, Charset charset) { + char[] chars = data.toCharArray(); + byte[] result = new byte[chars.length]; + for (int i = 0; i < chars.length; i++) { + result[i] = (byte) chars[i]; + } + return new String(result, 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); diff --git a/src/main/java/com/yexuejc/base/util/ObjUtil.java b/src/main/java/com/yexuejc/base/util/ObjUtil.java index 0ecf378..51f70fa 100644 --- a/src/main/java/com/yexuejc/base/util/ObjUtil.java +++ b/src/main/java/com/yexuejc/base/util/ObjUtil.java @@ -1,5 +1,7 @@ package com.yexuejc.base.util; +import com.yexuejc.base.annotation.ToUeProperty; + import java.io.*; import java.lang.reflect.Field; import java.time.LocalDate; diff --git a/src/test/java/com/yexuejc/base/util/ObjUtilTest.java b/src/test/java/com/yexuejc/base/util/ObjUtilTest.java index 5a8a22f..350ccd8 100644 --- a/src/test/java/com/yexuejc/base/util/ObjUtilTest.java +++ b/src/test/java/com/yexuejc/base/util/ObjUtilTest.java @@ -1,5 +1,7 @@ package com.yexuejc.base.util; +import com.yexuejc.base.annotation.ToUeProperty; + import java.io.Serializable; import java.math.BigDecimal; import java.time.LocalDateTime;