文章首发于我的github博客

需求

客户的开发测试环境将做迁移。因此需要对zookeeper上的重要的数据以CSV文件格式做备份。

本文通过Apache的commons-csv操作CSV文件。官网地址:http://commons.apache.org/proper/commons-csv/

基本概念

维基百科对CSV的解释:

逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本)。纯文本意味着该文件是一个字符序列,不含必须象二进制数字那样被解读的数据。CSV文件由任意数目的记录组成,记录间以某种换行符分隔;每条记录由字段组成,字段间的分隔符是其它字符或字符串,最常见的是逗号或制表符。通常,所有记录都有完全相同的字段序列。

代码

API使用很简单,直接上代码了。

  • 依赖包:
    <properties>
<slf4j.version>1.7.2</slf4j.version>
<log4j.version>1.2.17</log4j.version>
</properties> <dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<version>1.5</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
</dependencies>
  • 配置文件csv.properties:
# csv file output path(write)
csvfile.output.path=D:/zk-backup/zk-privilige.csv
# csv file input path(read)
csvfile.input.path=D:/zk-backup/zk-privilige.csv
#csvfile.input.path=/opt/apps/zk-recovery/zk-privilige.csv
# csv header,使用逗号分隔
csv.header=id,name,designation,company
  • 工具类:

① CSVWriter.java

package com.yeyouluo.csv.util;

import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List; import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import org.apache.log4j.Logger; /**
* 写CSV工具类
* @author yeyouluo
*
*/
public class CSVWriter { private static final Logger logger = Logger.getLogger(CSVWriter.class); /**
* 写CSV文件
* @param csvFile csv文件名称
* @param fileHeader 文件头
* @param content 内容
* @throws IOException
*/
public static void write(final String csvFile, final String[] fileHeader, List<String[]> content)
throws IOException {
BufferedWriter writer = Files.newBufferedWriter(Paths.get(csvFile));
CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT.withHeader(fileHeader)); for (String[] c : content) {
csvPrinter.printRecord(Arrays.asList(c));
}
csvPrinter.flush();
logger.info( "====> 成功写入CSV文件。文件路径:" + csvFile ); }
}

②CSVReaderWithlHeader.java

package com.yeyouluo.csv.util;

import java.io.IOException;
import java.io.Reader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List; import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord; /**
* 读带文件头的CSV文件工具类
* @author yeyouluo
*
*/
public class CSVReaderWithlHeader {
/**
*
* @param csvFile CSV文件
* @param fileHeader CSV文件头
* @param skipHeader 是否跳过文件头
* @return CSV记录链表
* @throws IOException
*/
public static List<CSVRecord> read(final String csvFile, final String[] fileHeader, boolean skipHeader)
throws IOException {
CSVFormat format; if (skipHeader) {
// 这里显式地配置一下CSV文件的Header,然后设置跳过Header(要不然读的时候会把头也当成一条记录)
format = CSVFormat.DEFAULT.withHeader(fileHeader).withFirstRecordAsHeader().withIgnoreHeaderCase()
.withTrim();
// format = CSVFormat.DEFAULT.withHeader(fileHeader)
// .withIgnoreHeaderCase().withTrim().withSkipHeaderRecord();
} else {
format = CSVFormat.DEFAULT.withHeader(fileHeader).withIgnoreHeaderCase().withTrim();
}
Reader reader = Files.newBufferedReader(Paths.get(csvFile)); CSVParser csvParser = new CSVParser(reader, format);
return csvParser.getRecords();
} /**
* 读取CSV文件,默认跳过文件头
* @param csvFile CSV文件
* @param fileHeader CSV文件头
* @return CSV记录链表
* @throws IOException
*/
public static List<CSVRecord> read(final String csvFile, final String[] fileHeader)
throws IOException{
return read(csvFile, fileHeader, true);
} }
  • 测试类

① CSVWriteService.java

package com.yeyouluo.csv.service;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties; import org.apache.log4j.Logger; import com.yeyouluo.csv.util.CSVWriter; /**
* 写CSV
* @author yeyouluo
*
*/
public class CSVWriteService {
private static final Logger logger = Logger.getLogger(CSVWriter.class); private static String csvFile; // csv文件路径 private static String[] fileHeader; // csv文件头 static {
// 读取配置文件
Properties prop = new Properties();
InputStream in = CSVWriter.class.getResourceAsStream("/csv.properties");
try {
prop.load(new InputStreamReader(in,"UTF-8"));
String root = CSVWriter.class.getResource("/").getPath();
csvFile = prop.getProperty("csvfile.output.path");
String headers = prop.getProperty("csv.header");
fileHeader = headers.split(",");
} catch (Exception e) {
logger.error("",e);
} finally {
if( in != null ) {
try {
in.close();
} catch (IOException e) {
logger.error("",e);
}
}
} // 创建父目录
File parentDir = new File(csvFile).getParentFile();
if( !parentDir.exists() ) {
logger.warn("CSV文件父目录不存在,即将创建...");
parentDir.mkdirs();
}
} public void wirte(List<String[]> content) {
try {
CSVWriter.write(csvFile, fileHeader, content);
} catch (IOException e) {
logger.error("写CSV文件出现问题",e);
}
} public static void main(String[] args) {
List<String[]> list = new ArrayList<String[]>();
list.add(new String[] {"1", "Sundar Pichai ♥", "CEO", "Google"});
list.add(new String[] {"2", "Satya Nadella", "CEO", "Microsoft"});
list.add(new String[] {"3", "Tim cook", "CEO", "Apple"});
list.add(new String[] {"4", "Mark Zuckerberg", "CEO", "Facebook"}); CSVWriteService csvWriteService = new CSVWriteService();
csvWriteService.wirte(list);
}
}

②CSVReaderWithlHeaderService.java

package com.yeyouluo.csv.service;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties; import org.apache.commons.csv.CSVRecord;
import org.apache.log4j.Logger; import com.yeyouluo.csv.util.CSVReaderWithlHeader; /**
* 读CSV
* @author yeyouluo
*
*/
public class CSVReaderWithlHeaderService { private static final Logger logger = Logger.getLogger(CSVReaderWithlHeaderService.class); private static String csvFile; // csv文件路径 private static String[] fileHeader; // csv文件头 static {
// 读取配置文件
Properties prop = new Properties();
InputStream in = CSVReaderWithlHeaderService.class.getResourceAsStream("/csv.properties");
try {
prop.load(new InputStreamReader(in,"UTF-8"));
String root = CSVReaderWithlHeaderService.class.getResource("/").getPath();
csvFile = prop.getProperty("csvfile.input.path");
String headers = prop.getProperty("csv.header");
fileHeader = headers.split(",");
} catch (Exception e) {
logger.error("",e);
} finally {
if( in != null ) {
try {
in.close();
} catch (IOException e) {
logger.error("",e);
}
}
} // 创建父目录
File parentDir = new File(csvFile).getParentFile();
if( !parentDir.exists() ) {
logger.warn("CSV文件父目录不存在,即将创建...");
parentDir.mkdirs();
}
} public void read() {
try {
List<CSVRecord> list = CSVReaderWithlHeader.read(csvFile, fileHeader);
for (CSVRecord csvRecord : list) {
// Accessing values by the names assigned to each column String id = csvRecord.get("ID");
String name = csvRecord.get("Name");
String designation = csvRecord.get("Designation");
String company = csvRecord.get("Company"); System.out.println("Record No - " + csvRecord.getRecordNumber());
System.out.println("---------------");
System.out.println("ID : " + id);
System.out.println("Name : " + name);
System.out.println("Designation : " + designation);
System.out.println("Company : " + company);
System.out.println("---------------\n\n");
}
} catch (IOException e) {
logger.error("读取CSV文件出现错误",e);
}
} public static void main(String[] args) {
CSVReaderWithlHeaderService service = new CSVReaderWithlHeaderService();
service.read();
} }

执行结果

  • 执行CSVWriteService.java
2018-03-03 11:05:43,551 [main] WARN  [com.yeyouluo.csv.util.CSVWriter] - CSV文件父目录不存在,即将创建...
2018-03-03 11:05:43,590 [main] INFO [com.yeyouluo.csv.util.CSVWriter] - ====> 成功写入CSV文件。文件路径:D:/zk-backup/zk-privilige.csv
  • 执行CSVReaderWithlHeaderService.java
Record No - 1
---------------
ID : 1
Name : Sundar Pichai ♥
Designation : CEO
Company : Google
--------------- Record No - 2
---------------
ID : 2
Name : Satya Nadella
Designation : CEO
Company : Microsoft
--------------- Record No - 3
---------------
ID : 3
Name : Tim cook
Designation : CEO
Company : Apple
--------------- Record No - 4
---------------
ID : 4
Name : Mark Zuckerberg
Designation : CEO
Company : Facebook
---------------

源码打包下载

链接: https://pan.baidu.com/s/1qZZru2K 密码: 866h

参考网址

使用commons-csv简单读写CSV文件的更多相关文章

  1. 使用csv模块读写csv格式文件

    import csv class HandleCsv: ''' csv文件处理类 ''' def __init__(self, filename): ''' 构造器 :param filename: ...

  2. python3使用csv模块读写csv文件

    python3使用csv模块读写csv文件 读取csv文件: import csv #打开文件,用with打开可以不用去特意关闭file了,python3不支持file()打开文件,只能用open() ...

  3. C# 简单读写ini文件帮助类 INIHelp

    软件里需要读取一些初始化信息, 决定用ini来做,简单方便. 于是查了一写代码,自己写了一个帮助类. INI文件格式是某些平台或软件上的配置文件的非正式标准, 以节(section)和键(key)构成 ...

  4. 使用 Apache Commons CSV 读写 CSV 文件

    有时候,我们需要读写 CSV 文件,在这里给大家分享Apache Commons CSV,读写 CSV 文件非常方便. 具体官方文档请访问Apache Commons CSV. 官方文档已经写得很详细 ...

  5. 一文综述python读写csv xml json文件各种骚操作

      Python优越的灵活性和易用性使其成为最受欢迎的编程语言之一,尤其是对数据科学家而言.这在很大程度上是因为使用Python处理大型数据集是很简单的一件事情. 如今,每家科技公司都在制定数据战略. ...

  6. C#中XmlTextWriter读写xml文件详细介绍

    XmlTextWriter类允许你将XML写到一个文件中去.这个类包含了很多方法和属性,使用这些属性和方法可以使你更容易地处理XML.为了使用这个类,你必须首先创建一个新的XmlTextWriter对 ...

  7. 用opencsv文件读写CSV文件

    首先明白csv文件长啥样儿: 用excel打开就变成表格了,看不到细节 推荐用其它简单粗暴一点儿的编辑器,比如Notepad++, csv文件内容如下: csv文件默认用逗号分隔各列. 有了基础的了解 ...

  8. 使用Python读写csv文件的三种方法

    Python读写csv文件 觉得有用的话,欢迎一起讨论相互学习~Follow Me 前言 逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是 ...

  9. python3读写csv文件

    python读取CSV文件   python中有一个读写csv文件的包,直接import csv即可.利用这个python包可以很方便对csv文件进行操作,一些简单的用法如下. 1. 读文件 csv_ ...

随机推荐

  1. Nginx日志中的金矿 -- 好文收藏

    转:http://www.infoq.com/cn/articles/nignx-log-goldmine Nginx(读作Engine-X)是现在最流行的负载均衡和反向代理服务器之一.如果你是一名中 ...

  2. _3_body_标签

    创:20_3_2017修:5_4_2017 什么是div标签? div 双 -- div标签没有任何默认属性 -可以任意写入样式和内容,和 水一样,水自然平凡而又最多 什么是h1标签? h1 标题(双 ...

  3. java中String的.trim()方法

    该方法去除两边的空白符 原理: 看看源码实现 public String trim() { int len = value.length; ; char[] val = value; /* avoid ...

  4. Linux exec与文件描述符

    看到好几篇文章讲述exec都是一知半解,所以我尽量说的清楚明白一些.本文首先讲述Linux文件描述符,然后是exec,最后举例说明exec I/O重定向及其用法. 概念:exec命令用于调用并执行指令 ...

  5. 自己模拟的一个简单的tomcat

    servlet容器的职责 总的来说,一个全功能的servlet容器会为servlet的每个HTTP请求做下面的一些工作: 1,当第一次调用servlet的时候,加载该servlet类并调用servle ...

  6. MySQL权限详解

    MySQL权限级别介绍 MySQL权限级别 全局性的管理权限,作用于整个MySQL实例级别 数据库级别的权限,作用于某个指定的数据库上或者所有的数据库上 数据库对象级别的权限,作用于指定的数据库对象上 ...

  7. Mysql Innodb 锁机制

    latch与lock latch 可以认为是应用程序中的锁,可以称为闩锁(轻量级的锁) 因为其要求锁定的时间必须要非常短,若持续时间长,则会导致应用性能非常差,在InnoDB存储引擎中,latch又可 ...

  8. C程序结构

    从程序流程的角度来看,C语言中的语句可以分为3种基本结构:顺序结构.分支结构和循环结构. ① 顺序结构的执行过程如图5-1所示.在这种结构中,程序会顺序执行各条语句. ② 分支结构的执行过程如图5-2 ...

  9. 将本地目录上传值git仓库

    创建git仓库 以github为例,登录账号建立一个仓库,然后将仓库地址copy下来. 本地目录 初始化 $ git init 添加至版本库 $ git add -A 提交 $ git commit ...

  10. 探索从 MVC 到 MVVM + Flux 架构模式的转变

    本文首发于 my blog 在业务中一般 MVVM 框架一般都会配合上数据状态库(redux, mobx 等)一起使用,本文会通过一个小 demo 来讲述为什么会引人数据状态库. 从 MVC 到 MV ...