成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

基于 java 注解的 csv 讀寫框架更加簡(jiǎn)單靈活

includecmath / 1183人閱讀

摘要:創(chuàng)作原由以前覺得文件的讀寫非常簡(jiǎn)單,就懶得封裝。為了解決上述問題,此框架應(yīng)運(yùn)而生。寫入文件其中列表構(gòu)建構(gòu)建基于注解的測(cè)試列表列表你好生成文件內(nèi)容名稱生日你好讀取文件測(cè)試日志信息你好集合類有時(shí)候?qū)ο笾袝?huì)包含數(shù)組等常見集合。

CSV

基于 java 注解的 csv 讀寫框架。

相關(guān)框架

Apache commons-csv

super-csv

簡(jiǎn)單看了下,這兩個(gè)框架提供的特性都非常的基礎(chǔ)。

創(chuàng)作原由

以前覺得 csv 文件的讀寫非常簡(jiǎn)單,就懶得封裝。

最近一個(gè)月寫了兩次 csv 文件相關(guān)的東西,發(fā)現(xiàn)要處理的細(xì)節(jié)還是有的,還浪費(fèi)比較多的時(shí)間。

比如:

UTF-8 中文編碼使用 excel 打開亂碼,因?yàn)槿鄙?BOM 頭。

不同類型字段轉(zhuǎn)化為字符串,順序的指定,head 頭的指定,如果手寫都會(huì)很繁瑣。

讀取的時(shí)候最后 , 后無(wú)元素,split 會(huì)缺失等。

為了解決上述問題,此框架應(yīng)運(yùn)而生。

特性

Fluent 流式寫法

基于 java 注解,支持自定義的轉(zhuǎn)換和靈活配置

內(nèi)置 8 大基本類型以及 String 類型轉(zhuǎn)換

解決 Excel 直接打開,utf-8 亂碼問題

支持集合、數(shù)組、Map 的存取

支持對(duì)象中內(nèi)嵌其他對(duì)象

支持特殊字符轉(zhuǎn)義

變更日志

CHANGE_LOG.md

開源地址

csv

快速開始 環(huán)境

jdk7+

maven 3.x

maven 引入

    com.github.houbb
    csv
    0.0.6
示例代碼

User.java

演示基本類型的轉(zhuǎn)換

public class User {

    private String name;

    private int age;

    private float score;

    private double money;

    private boolean sex;

    private short level;

    private long id;

    private char status;

    private byte coin;

    //Getter & Setter & toString()
}

對(duì)象列表構(gòu)建

    /**
     * 構(gòu)建通用測(cè)試列表
     * @return 列表
     */
    private List buildCommonList() {
        User user = new User();
        short s = 4;
        byte b = 1;
        user.age(10)
        .name("你好")
        .id(1L)
        .score(60)
        .coin(b)
        .level(s)
        .money(200)
        .sex(true)
        .status("Y");
        return Arrays.asList(user);
    }
寫入

測(cè)試代碼

public void commonTest() {
    final String path = "src	est
esourcescommon.csv";
    CsvWriteBs.newInstance(path)
            .write(buildCommonList());
}

文件生成

name,age,score,money,sex,level,id,status,coin
你好,10,60.0,200.0,true,4,1,Y,1
讀取
public void commonTest() {
    final String path = "src	est
esourcescommon.csv";
    List userList = CsvReadBs.newInstance(path)
            .read(User.class);
    System.out.println(userList);
}

日志信息

[User{name="你好", age=10, score=60.0, money=200.0, sex=true, level=4, id=1, status=Y, coin=1}]
引導(dǎo)類 為什么需要引導(dǎo)類

為了靈活的配置和默認(rèn)配置并存,使用工具類會(huì)大大降低靈活性。

為了用戶使用的便利性,和后期拓展的靈活性。

引導(dǎo)類

CSV 有兩個(gè)引導(dǎo)類:

名稱 作用
CsvWriteBs csv 文件寫入引導(dǎo)類
CsvReadBs csv 文件讀取引導(dǎo)類
CsvWriteBs
方法 默認(rèn)值 說(shuō)明
newInstance(final String path) 必填 創(chuàng)建實(shí)例,并且指定待寫入文件路徑。
path (final String path) 配置文件路徑,只有重新指定 path 路徑時(shí)需要調(diào)用。
writeHead(boolean writeBom) true 是否寫入 head 頭,如果想指定名稱,可以結(jié)合注解。只有無(wú) head 信息時(shí),會(huì)寫入。
writeBom(boolean writeBom) true 是否寫入 UTF8 BOM 頭,只有文件為空時(shí)才會(huì)寫入。
charset(String charset) UTF-8 指定文件編碼
sort(ISort sort) NoSort 默認(rèn)不進(jìn)行字段排序
write(List list) 無(wú) 待寫入的文件列表
escape false 是否進(jìn)行特殊字符的轉(zhuǎn)換
CsvReadBs
方法 默認(rèn)值 說(shuō)明
newInstance(final String path) 必填 創(chuàng)建實(shí)例,并且指定待讀取文件路徑。
path (final String path) 配置文件路徑,只有重新指定 path 路徑時(shí)需要調(diào)用。
charset(String charset) UTF-8 指定文件編碼
sort(ISort sort) NoSort 默認(rèn)不進(jìn)行字段排序
startIndex(int startIndex) 1 文件的第二行,默認(rèn)第一行是 head
endIndex(int endIndex) 文件的最后一行
escape false 是否進(jìn)行特殊字符的轉(zhuǎn)換
Csv 注解 注解屬性說(shuō)明

用于待處理對(duì)象的字段上。

    /**
     * 字段顯示名稱
     * 1. 默認(rèn)使用 field.name
     * @return 顯示名稱
     */
    String label() default "";

    /**
     * 讀取是否需要
     * @return 是
     */
    boolean readRequire() default true;

    /**
     * 寫入是否需要
     * @return 是
     */
    boolean writeRequire() default true;

    /**
     * 讀取轉(zhuǎn)換
     * @return 處理實(shí)現(xiàn)類
     */
    Class readConverter() default CommonReadConverter.class;

    /**
     * 寫入轉(zhuǎn)換
     * @return 處理實(shí)現(xiàn)類
     */
    Class writeConverter() default StringWriteConverter.class;
屬性概覽表
屬性 默認(rèn)值 說(shuō)明
label 字段名稱 用于 csv 頭生成
readRequire true 是否需要從 csv 文件讀取
writeRequire true 當(dāng)前字段是否需要寫入 csv 文件
readConverter CommonReadConverter 將 csv 中的字符串轉(zhuǎn)化為當(dāng)前字段類型,支持 8 大基本類型+String
writeConverter StringWriteConverter 直接調(diào)用當(dāng)前字段值 toString() 方法,null 直接為空字符串

其中 readConverter/writeConverter 支持用戶自定義

字段注解 對(duì)象定義
public class UserAnnotation {

    @Csv(label = "名稱")
    private String name;

    @Csv(label = "密碼", readRequire = false, writeRequire = false)
    private String password;

    @Csv(label = "生日", readConverter = ReadDateConvert.class, writeConverter = WriteDateConvert.class)
    private Date birthday;

    //Getter & Setter & toString()
}
ReadDateConvert/WriteDateConvert

使我們自定義的針對(duì) Date 的轉(zhuǎn)換實(shí)現(xiàn)。

Write

public class WriteDateConvert implements IWriteConverter {

    @Override
    public String convert(Date value) {
        DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
        return dateFormat.format(value);
    }

}

ReadDateConvert

public class ReadDateConvert implements IReadConverter {

    @Override
    public Date convert(String value, Class fieldType) {
        try {
            DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
            return dateFormat.parse(value);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

}
寫入文件
public void annotationTest() {
    final String path = "src	est
esourcesannotation.csv";
    CsvWriteBs.newInstance(path)
            .write(buildAnnotationList());
}

其中列表構(gòu)建:

/**
 * 構(gòu)建基于注解的測(cè)試列表
 * @return 列表
 */
private List buildAnnotationList() {
    UserAnnotation user = new UserAnnotation();
    user.name("你好")
            .password("123")
            .birthday(new Date());
    return Arrays.asList(user);
}

生成文件內(nèi)容

名稱,生日
你好,20190603
讀取文件測(cè)試
public void annotationTest() {
     final String path = "src	est
esourcesannotation.csv";
     List userList = CsvReadBs.newInstance(path)
             .read(UserAnnotation.class);
     System.out.println(userList);
}

日志信息

[UserAnnotation{name="你好", password="null", birthday=Mon Jun 03 00:00:00 CST 2019}]
集合類

有時(shí)候?qū)ο笾袝?huì)包含數(shù)組、Map、Collection 等常見集合。

為了存儲(chǔ)的便利性,默認(rèn)提供集合的相關(guān)支持。

特性和普通字段保持一致,如果指定注解轉(zhuǎn)換,則以注解為準(zhǔn)。

使用示例

UserCollection.java

用于演示集合的對(duì)象

public class UserCollection {

    private String[] arrays;

    private LinkedList lists;

    private Map maps;

    private Set sets;

    //Getter/Setter/toString()
}
存儲(chǔ)

待存儲(chǔ)對(duì)象的構(gòu)建

/**
 * 構(gòu)建基于集合的測(cè)試列表
 * @return 列表
 * @since 0.0.3
 */
private List buildCollectionList() {
    UserCollection user = new UserCollection();
    String[] arrays = new String[]{"a", "b", "c"};
    LinkedList lists = new LinkedList<>(Arrays.asList(arrays));
    Map maps = new HashMap<>();
    maps.put("key", "value");
    maps.put("key2", "value2");
    Set sets = new HashSet<>();
    sets.add("set1");
    sets.add("set2");

    user.setLists(lists);
    user.setArrays(arrays);
    user.setMaps(maps);
    user.setSets(sets);
    return Arrays.asList(user);
}

執(zhí)行存儲(chǔ)

public void collectionTest() {
    final String path = "src	est
esourcescollection.csv";
    CsvWriteBs.newInstance(path)
            .write(buildCollectionList());
}

存儲(chǔ)效果

?arrays,lists,maps,sets
a|b,a|b|c,key2=value2|key=value,set1|set2
讀取

測(cè)試類

public void collectionTest() {
    final String path = "src	est
esourcescollection.csv";
    List userList = CsvReadBs.newInstance(path)
            .read(UserCollection.class);
    System.out.println(userList);
}

測(cè)試日志

[UserCollection{arrays=[a, b], lists=[a, b, c], maps={key=value, key2=value2}, sets=[set2, set1]}]
注意

為了保證 csv 以 , 分隔的統(tǒng)一性。

集合使用 | 進(jìn)行分隔,其中 map 的 key/value 分隔,用到了 =。

在使用時(shí)要注意,不要包含上述的符號(hào),否則會(huì)出現(xiàn)解析錯(cuò)亂。

ps: 如果確實(shí)用到這些字符,可以見后面的特殊字符轉(zhuǎn)義功能。

支持內(nèi)嵌對(duì)象

有時(shí)候我們希望像使用 mongoDB 一樣,非常方便的存取 csv 的嵌套對(duì)象。

對(duì)于普通的 csv 都沒有實(shí)現(xiàn)這個(gè)特性,本次做了一個(gè)嘗試,支持內(nèi)嵌對(duì)象的存取。

取舍

就像 csv 的簡(jiǎn)單,需要用到符號(hào) , 一樣。

內(nèi)嵌對(duì)象為了不破壞 csv 的規(guī)范,使用了符號(hào) :。

換言之,也就是對(duì)象內(nèi)容中不能使用這個(gè)符號(hào)。

后期會(huì)針對(duì)出現(xiàn)的符號(hào)進(jìn)行轉(zhuǎn)義,避免這種沖突。

測(cè)試案例 示例對(duì)象

UserEntry.java

public class UserEntry {

    /**
     * 名稱
     */
    private String name;

    /**
     * 內(nèi)嵌的用戶信息
     */
    @CsvEntry
    private User user;

    //Getter/Setter/ToString
}

這里在需要內(nèi)嵌的對(duì)象上使用注解 @CsvEntry 表示需要進(jìn)行內(nèi)嵌的對(duì)象轉(zhuǎn)換。

User.java

其中 User 對(duì)象是原來(lái)使用的普通 java 對(duì)象

public class User {

    private String name;

    private int age;

    private float score;

    private double money;

    private boolean sex;

    private short level;

    private long id;

    private char status;

    private byte coin;

    //Getter/Setter/ToString
}
寫入測(cè)試
public void entryTest() {
    final String path = "src	est
esourcesentry.csv";
    CsvWriteBs.newInstance(path)
            .write(buildEntryList());
}

buildEntryList()

負(fù)責(zé)對(duì)象構(gòu)建代碼,內(nèi)容如下:

/**
 * 用戶明細(xì)列表
 * @return 明細(xì)列表
 * @since 0.0.5
 */
private List buildEntryList() {
    UserEntry userEntry = new UserEntry();
    userEntry.name("test");
    userEntry.user(buildCommonList().get(0));
    return Collections.singletonList(userEntry);
}

buildCommonList()

private List buildCommonList() {
    User user = new User();
    short s = 4;
    byte b = 1;
    user.age(10)
    .name("你好")
    .id(1L)
    .score(60)
    .coin(b)
    .level(s)
    .money(200)
    .sex(true)
    .status("Y");
    return Arrays.asList(user);
}

生成文件效果

name,user
test,你好:10:60.0:200.0:true:4:1:Y:1

如你所見,這里內(nèi)嵌對(duì)象的屬性使用了 : 進(jìn)行分隔。

讀取測(cè)試
public void entryTest() {
    final String path = "src	est
esourcesentry.csv";
    List userList = CsvReadBs.newInstance(path)
            .read(UserEntry.class);
    System.out.println(userList);
}

輸出信息

[UserEntry{name="test", user=User{name="你好", age=10, score=60.0, money=200.0, sex=true, level=4, id=1, status=Y, coin=1}}]
特殊字符轉(zhuǎn)義

在實(shí)際使用中,有時(shí)候我們會(huì)用到 ,|:=。

這幾個(gè)被使用的特殊字符。

如果你希望這些特殊的字符被正確的存取,那么可以使用 escape 屬性執(zhí)行。

特殊字符的轉(zhuǎn)換
原始 轉(zhuǎn)義后
, &CSV_COMMA;
` ` &CSV_OR;
: &CSV_COLON;
= &CSV_EUQAL;

下面演示一下如何使用

暫時(shí)轉(zhuǎn)義字符不支持自定義。

測(cè)試代碼 寫入測(cè)試
public void escapeTest() {
    final String path = "src	est
esourcesescape.csv";
    CsvWriteBs.newInstance(path)
            .escape(true)
            .write(buildUserEscapeList());
}

生成文件效果

name,map,nameList,user
one&CSV_COMMA;one,key&CSV_EUQAL;key=value&CSV_EUQAL;value,one&CSV_OR;one|two&CSV_OR;two,entry&CSV_COLON;name:0:0.0:0.0:false:0:0: :0
相關(guān)代碼

UserEscape.java

其中用到的對(duì)象為:

public class UserEscape {

    /**
     * 使用 ,
     */
    private String name;

    /**
     * 使用 map =
     */
    private Map map;

    /**
     * 使用 |
     */
    private List nameList;

    /**
     * 使用 :
     */
    @CsvEntry
    private User user;

    //Getter & Setter & ToString()
}

buildUserEscapeList()

構(gòu)建時(shí),特意使用了特殊的字符。

private List buildUserEscapeList() {
    UserEscape escape = new UserEscape();
    Map map = new HashMap<>();
    map.put("key=key", "value=value");
    User user = new User();
    user.name("entry:name");

    escape.name("one,one");
    escape.nameList(Arrays.asList("one|one", "two|two"));
    escape.map(map);
    escape.user(user);

    return Collections.singletonList(escape);
}
讀取測(cè)試
public void escapeTest() {
    final String path = "src	est
esourcesescape.csv";
    List userList = CsvReadBs.newInstance(path)
            .escape(true)
            .read(UserEscape.class);
    System.out.println(userList);
}

日志信息

[UserEscape{name="one,one", nameList=[one|one, two|two], user=User{name="entry:name", age=0, score=0.0, money=0.0, sex=false, level=0, id=0, status= , coin=0}, map={key=key=value=value}}]
后續(xù)設(shè)計(jì) 更豐富的類型支持

支持更多的 java 常見類型。

更靈活的配置

比如支持用戶自定義轉(zhuǎn)義字符

支持文件的寫入模式等等。

開源地址

csv

可以查看相關(guān)代碼。

為了便于其他人閱讀和使用,代碼擁有詳細(xì)的注釋。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/77856.html

相關(guān)文章

  • 基于 java 注解 csv 文件讀寫框架

    摘要:基于注解生成加簽驗(yàn)簽。是否寫入頭,建議第一次寫入指定,避免中文亂碼指定文件編碼默認(rèn)不進(jìn)行字段排序無(wú)待寫入的文件列表方法默認(rèn)值說(shuō)明必填創(chuàng)建實(shí)例,并且指定待讀取文件路徑。 csv 基于 java 注解生成加簽驗(yàn)簽 csv。 開源地址: github csv) 創(chuàng)作原由 以前覺得 csv 文件的多寫非常簡(jiǎn)單,就懶得封裝。 最近一個(gè)月寫了兩次 csv 文件相關(guān)的東西,發(fā)現(xiàn)要處理的細(xì)節(jié)還是有的,...

    Gemini 評(píng)論0 收藏0
  • CSV-03- csv 讀寫框架支持?jǐn)?shù)組、Map、Collection 等常見集合

    摘要:集合類有時(shí)候?qū)ο笾袝?huì)包含數(shù)組等常見集合。為了存儲(chǔ)的便利性,默認(rèn)提供集合的相關(guān)支持。特性和普通字段保持一致,如果指定注解轉(zhuǎn)換,則以注解為準(zhǔn)。集合使用進(jìn)行分隔,其中的分隔,用到了。在使用時(shí)要注意,不要包含上述的符號(hào),否則會(huì)出現(xiàn)解析錯(cuò)亂。 集合類 有時(shí)候?qū)ο笾袝?huì)包含數(shù)組、Map、Collection 等常見集合。 為了存儲(chǔ)的便利性,默認(rèn)提供集合的相關(guān)支持。 特性和普通字段保持一致,如果指定注...

    leiyi 評(píng)論0 收藏0
  • spring retry, guava retrying 整合-sisyphus java 重試框

    摘要:特性支持過程式編程基于字節(jié)碼的代理重試基于注解的重試,允許自定義注解無(wú)縫接入接口與注解的統(tǒng)一解決與中的不足之處設(shè)計(jì)目的綜合了和的優(yōu)勢(shì)?;谧止?jié)碼實(shí)現(xiàn)的代理重試,可以不依賴。提供基于代碼模式字節(jié)碼增強(qiáng)實(shí)現(xiàn)的方式。 Sisyphus 支持過程式編程和注解編程的 java 重試框架。 特性 支持 fluent 過程式編程 基于字節(jié)碼的代理重試 基于注解的重試,允許自定義注解 無(wú)縫接入 sp...

    宋華 評(píng)論0 收藏0
  • 后端經(jīng)驗(yàn)

    摘要:在結(jié)構(gòu)上引入了頭結(jié)點(diǎn)和尾節(jié)點(diǎn),他們分別指向隊(duì)列的頭和尾,嘗試獲取鎖入隊(duì)服務(wù)教程在它提出十多年后的今天,已經(jīng)成為最重要的應(yīng)用技術(shù)之一。隨著編程經(jīng)驗(yàn)的日積月累,越來(lái)越感覺到了解虛擬機(jī)相關(guān)要領(lǐng)的重要性。 JVM 源碼分析之 Jstat 工具原理完全解讀 http://click.aliyun.com/m/8315/ JVM 源碼分析之 Jstat 工具原理完全解讀 http:...

    i_garfileo 評(píng)論0 收藏0
  • Spring入門看這一篇就夠了

    摘要:甲乙交易活動(dòng)不需要雙方見面,避免了雙方的互不信任造成交易失敗的問題。這就是的核心思想。統(tǒng)一配置,便于修改。帶參數(shù)的構(gòu)造函數(shù)創(chuàng)建對(duì)象首先,就要提供帶參數(shù)的構(gòu)造函數(shù)接下來(lái),關(guān)鍵是怎么配置文件了。 前言 前面已經(jīng)學(xué)習(xí)了Struts2和Hibernate框架了。接下來(lái)學(xué)習(xí)的是Spring框架...本博文主要是引入Spring框架... Spring介紹 Spring誕生: 創(chuàng)建Spring的...

    superw 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

includecmath

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<