国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

基于 java 注解的 csv 讀寫框架更加簡單靈活

includecmath / 1173人閱讀

摘要:創作原由以前覺得文件的讀寫非常簡單,就懶得封裝。為了解決上述問題,此框架應運而生。寫入文件其中列表構建構建基于注解的測試列表列表你好生成文件內容名稱生日你好讀取文件測試日志信息你好集合類有時候對象中會包含數組等常見集合。

CSV

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

相關框架

Apache commons-csv

super-csv

簡單看了下,這兩個框架提供的特性都非常的基礎。

創作原由

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

最近一個月寫了兩次 csv 文件相關的東西,發現要處理的細節還是有的,還浪費比較多的時間。

比如:

UTF-8 中文編碼使用 excel 打開亂碼,因為缺少 BOM 頭。

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

讀取的時候最后 , 后無元素,split 會缺失等。

為了解決上述問題,此框架應運而生。

特性

Fluent 流式寫法

基于 java 注解,支持自定義的轉換和靈活配置

內置 8 大基本類型以及 String 類型轉換

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

支持集合、數組、Map 的存取

支持對象中內嵌其他對象

支持特殊字符轉義

變更日志

CHANGE_LOG.md

開源地址

csv

快速開始 環境

jdk7+

maven 3.x

maven 引入

    com.github.houbb
    csv
    0.0.6
示例代碼

User.java

演示基本類型的轉換

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()
}

對象列表構建

    /**
     * 構建通用測試列表
     * @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);
    }
寫入

測試代碼

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}]
引導類 為什么需要引導類

為了靈活的配置和默認配置并存,使用工具類會大大降低靈活性。

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

引導類

CSV 有兩個引導類:

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

用于待處理對象的字段上。

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

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

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

    /**
     * 讀取轉換
     * @return 處理實現類
     */
    Class readConverter() default CommonReadConverter.class;

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

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

字段注解 對象定義
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

使我們自定義的針對 Date 的轉換實現。

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());
}

其中列表構建:

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

生成文件內容

名稱,生日
你好,20190603
讀取文件測試
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}]
集合類

有時候對象中會包含數組、Map、Collection 等常見集合。

為了存儲的便利性,默認提供集合的相關支持。

特性和普通字段保持一致,如果指定注解轉換,則以注解為準。

使用示例

UserCollection.java

用于演示集合的對象

public class UserCollection {

    private String[] arrays;

    private LinkedList lists;

    private Map maps;

    private Set sets;

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

待存儲對象的構建

/**
 * 構建基于集合的測試列表
 * @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);
}

執行存儲

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

存儲效果

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

測試類

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

測試日志

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

為了保證 csv 以 , 分隔的統一性。

集合使用 | 進行分隔,其中 map 的 key/value 分隔,用到了 =

在使用時要注意,不要包含上述的符號,否則會出現解析錯亂。

ps: 如果確實用到這些字符,可以見后面的特殊字符轉義功能。

支持內嵌對象

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

對于普通的 csv 都沒有實現這個特性,本次做了一個嘗試,支持內嵌對象的存取。

取舍

就像 csv 的簡單,需要用到符號 , 一樣。

內嵌對象為了不破壞 csv 的規范,使用了符號 :

換言之,也就是對象內容中不能使用這個符號。

后期會針對出現的符號進行轉義,避免這種沖突。

測試案例 示例對象

UserEntry.java

public class UserEntry {

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

    /**
     * 內嵌的用戶信息
     */
    @CsvEntry
    private User user;

    //Getter/Setter/ToString
}

這里在需要內嵌的對象上使用注解 @CsvEntry 表示需要進行內嵌的對象轉換。

User.java

其中 User 對象是原來使用的普通 java 對象

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
}
寫入測試
public void entryTest() {
    final String path = "src	est
esourcesentry.csv";
    CsvWriteBs.newInstance(path)
            .write(buildEntryList());
}

buildEntryList()

負責對象構建代碼,內容如下:

/**
 * 用戶明細列表
 * @return 明細列表
 * @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

如你所見,這里內嵌對象的屬性使用了 : 進行分隔。

讀取測試
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}}]
特殊字符轉義

在實際使用中,有時候我們會用到 ,|:=

這幾個被使用的特殊字符。

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

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

下面演示一下如何使用

暫時轉義字符不支持自定義。

測試代碼 寫入測試
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
相關代碼

UserEscape.java

其中用到的對象為:

public class UserEscape {

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

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

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

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

    //Getter & Setter & ToString()
}

buildUserEscapeList()

構建時,特意使用了特殊的字符。

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);
}
讀取測試
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}}]
后續設計 更豐富的類型支持

支持更多的 java 常見類型。

更靈活的配置

比如支持用戶自定義轉義字符

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

開源地址

csv

可以查看相關代碼。

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

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/77856.html

相關文章

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

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

    Gemini 評論0 收藏0
  • CSV-03- csv 讀寫框架支持數組、Map、Collection 等常見集合

    摘要:集合類有時候對象中會包含數組等常見集合。為了存儲的便利性,默認提供集合的相關支持。特性和普通字段保持一致,如果指定注解轉換,則以注解為準。集合使用進行分隔,其中的分隔,用到了。在使用時要注意,不要包含上述的符號,否則會出現解析錯亂。 集合類 有時候對象中會包含數組、Map、Collection 等常見集合。 為了存儲的便利性,默認提供集合的相關支持。 特性和普通字段保持一致,如果指定注...

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

    摘要:特性支持過程式編程基于字節碼的代理重試基于注解的重試,允許自定義注解無縫接入接口與注解的統一解決與中的不足之處設計目的綜合了和的優勢。基于字節碼實現的代理重試,可以不依賴。提供基于代碼模式字節碼增強實現的方式。 Sisyphus 支持過程式編程和注解編程的 java 重試框架。 特性 支持 fluent 過程式編程 基于字節碼的代理重試 基于注解的重試,允許自定義注解 無縫接入 sp...

    宋華 評論0 收藏0
  • 后端經驗

    摘要:在結構上引入了頭結點和尾節點,他們分別指向隊列的頭和尾,嘗試獲取鎖入隊服務教程在它提出十多年后的今天,已經成為最重要的應用技術之一。隨著編程經驗的日積月累,越來越感覺到了解虛擬機相關要領的重要性。 JVM 源碼分析之 Jstat 工具原理完全解讀 http://click.aliyun.com/m/8315/ JVM 源碼分析之 Jstat 工具原理完全解讀 http:...

    i_garfileo 評論0 收藏0
  • Spring入門看這一篇就夠了

    摘要:甲乙交易活動不需要雙方見面,避免了雙方的互不信任造成交易失敗的問題。這就是的核心思想。統一配置,便于修改。帶參數的構造函數創建對象首先,就要提供帶參數的構造函數接下來,關鍵是怎么配置文件了。 前言 前面已經學習了Struts2和Hibernate框架了。接下來學習的是Spring框架...本博文主要是引入Spring框架... Spring介紹 Spring誕生: 創建Spring的...

    superw 評論0 收藏0

發表評論

0條評論

includecmath

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<