文章首发于我的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. Redis-安装、启动

    安装Redis 下载redis安装包http://download.redis.io/redis-stable.tar.gz 解压安装包tar xzf redis-stable.tar.gz 安装cd ...

  2. 重温MFC

    1. Button控件 2. 旋转和高级编辑控件 3. 标签控件和属性页 4. 列表控件 5. 树控件 6. 进度条控件和滑动条控件 7. 滚动条 8.工具栏和状态栏

  3. Windows核心编程&进程

    1. 进程的定义 说白了进程就是一个正在运行的执行程序,包含内核对象和独立的地址空间,内核对象负责统计和管理进程信息,地址空间包括所有可执行文件或DLL 模块的代码和数据.动态内存分配(线程堆和栈的分 ...

  4. GIT工程迁移方法总结

    Git工程迁移方法总结 Git最近准备迁移一下位置,这里采用命令行的方式,做如下操作. 1.git init  初始化git仓库,这个时候发现本地文件夹多了个.git的文件夹. 2.git remot ...

  5. SQL SERVER 表最小行的一个纠结问题

    昨天一个同事突然问我,说他在SQL 2000数据库创建如下表的时候,突然碰到了下面一条警告信息.SQL脚本和警告信息如下: IF OBJECT_ID(N'Log') IS  NULL BEGINCRE ...

  6. Redis进阶实践之八Lua的Cjson在Linux下安装、使用和用C#调用Lua脚本

    一.引言         学习Redis也有一段时间了,感触还是颇多的,但是自己很清楚,路还很长,还要继续.上一篇文章简要的介绍了如何在Linux环境下安装Lua,并介绍了在Linux环境下如何编写L ...

  7. android EditText与TextView几个常用的属性

    android:maxLength="100"输入框最多输入的字数. android:maxEms="10"每行最多输入字符个数 android:textcol ...

  8. 【转】GPS静态观测网的设计指标

     GPS网的设计指标是指导GPS网设计量化因子,是评价GPS网设计优劣的数值标准.评价GPS网设计的优劣主要从以下三个因素考虑:1.质量(包括精度和可靠性):2.效率:3.费用. 一.GPS网设计的精 ...

  9. eclipse每次闪退后都提示查看\workspace\.metadata\.log

    错误如下: 找到<workspace>/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi"文件,将其删掉,再重启 ...

  10. JSP与HTML及前后分离

    JSP是什么 首先要知道JSP的本质其实是个Servlet,index.jsp在访问的时候首先会自动将该页面翻译生一个index_jsp.java文件,即Servlet代码. 打开这个类你会发现这个类 ...