java csv - 读写及其操作.
今天帮同学处理数据, 主要是从1w多条记录中随机获取8k条, 然后再从8k条记录中随机获取2k条记录. 最后将2k条记录中随机分成10组,使得每组的记录都不重复.
下面将我的代码都贴上来, 好以后处理csv文件.
- 首先使用第三方的jar文件 javcsv.jar : 链接: http://pan.baidu.com/s/1qW5b3u0 密码: qjmx
- 虽然该类库可以相对方便提供操作, 但是为了方便处理, 我将处理的字段都放在配置文件中, 然后将每一条记录都封装为Map<String, String>对象,我将读写的基础类封装为 CSVBasic:
package spt.csv; import java.io.Serializable;
import java.nio.charset.Charset; import spt.util.PropertyConfig; /**
* CSV文件操作基础类.
*/
abstract public class CSVBasic implements Serializable { private Charset charset; //编码.
private char delimiter; //分隔符.
private String fileName; /**
* 默认编码.
*
* @return
*/
public static Charset getDefaultCharset() {
return Charset.forName(PropertyConfig.getProperty("charset"));
} /**
* 默认分割符.
*
* @return
*/
public static char getDefaultDelimiter() {
return PropertyConfig.getProperty("delimiter").charAt(0);
} public String getFileName() {
return fileName;
} public void setFileName(String fileName) {
this.fileName = fileName;
} public Charset getCharset() {
return charset;
} public void setCharset(Charset charset) {
this.charset = charset;
} public void setDelimiter(char delimiter) {
this.delimiter = delimiter;
} public char getDelimiter() {
return delimiter;
} public CSVBasic() {} /**使用默认的分隔符和编码.
* @param fileName
*/
public CSVBasic(String fileName) {
this(fileName, getDefaultDelimiter(), getDefaultCharset());
} public CSVBasic(String fileName, char delimiter, Charset charset) {
setFileName(fileName);
setDelimiter(delimiter);
setCharset(charset);
} /**
*
*/
private static final long serialVersionUID = 7916808982930771124L;
}3.读取csv文件,并映射记录为List<Map<String, String>> 对象:
package spt.csv; import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import spt.util.PropertyConfig; import com.csvreader.CsvReader; /**
* 读取csv文件的类.
*/
public class Reader extends CSVBasic { private CsvReader reader; public CsvReader getReader() {
return reader;
} public void setReader(CsvReader reader) {
this.reader = reader;
} public Reader(String fileName) throws FileNotFoundException {
this(fileName, getDefaultDelimiter(), getDefaultCharset());
} public Reader(String fileName, char delimiter, Charset charset)
throws FileNotFoundException {
// set before getting.
super(fileName, delimiter, charset);
setReader(new CsvReader(fileName, delimiter, charset));
} /**根据字段列表,见每条记录映射为一个Map对象的列表.
* @param fieldNames
* 指定配置文件中字段名的'键'的列表.
* @return
*/
public List<Map<String, String>> getResult(List<String> fieldNames) {
// 每行中的每一个项是一个Map<String, String>的键值对.
List<Map<String, String>> lines = new ArrayList<Map<String, String>>(); CsvReader r = null;
try {
r = getReader();
r.readHeaders(); // 读取表头. Map<String, String> itemMap = null; // 每一条记录是一个Map<String, String>.
while (r.readRecord()) {
itemMap = new HashMap<String, String>();
String k = null;
// 每一条记录添加键值对.
for (String fieldName : fieldNames) {
// 字段名.
k = PropertyConfig.getProperty(fieldName);
itemMap.put(k, r.get(k));
}
lines.add(itemMap);
}
return lines;
} catch (IOException e) {
e.printStackTrace();
return null;
} finally {
if(r != null)
r.close();
}
} @Override
public String toString() {
return getFileName();
} /**
*
*/
private static final long serialVersionUID = -1712774594374451546L;
}4.将List<Map<String, String>>输出为csv文件的类:
package spt.csv; import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map; import com.csvreader.CsvWriter; /**
* csv文件写入类.
*/
public class Writer extends CSVBasic { private CsvWriter writer = null; public boolean write(List<String> fieldNames,
List<Map<String, String>> mapList) {
CsvWriter writer = null;
try {
writer = getWriter();
// 写入表头.
writer.writeRecord((String[]) fieldNames
.toArray(new String[fieldNames.size()]));
for (Map<String, String> map : mapList) {
// 存储每行记录.
String[] records = new String[fieldNames.size()];
for (int i = 0; i < fieldNames.size(); i++)
records[i] = map.get(fieldNames.get(i));
// 写入每行记录.
writer.writeRecord(records);
}
return true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
} finally {
if (writer != null)
writer.close();
}
} public Writer() {
this(null, getDefaultDelimiter(), getDefaultCharset());
} public Writer(String fileName) {
this(fileName, getDefaultDelimiter(), getDefaultCharset());
} public Writer(String fileName, char delimiter, Charset charset) {
super(fileName, delimiter, charset);
writer = new CsvWriter(fileName, delimiter, charset);
} public CsvWriter getWriter() {
return writer;
} public void setWriter(CsvWriter writer) {
this.writer = writer;
} /**
*
*/
private static final long serialVersionUID = -9141083858975437622L;
}5.表中有一个字段NYR, 表示时间, 由于需要将结果按照时间的先后顺序排序, 所以定义一个比较器:
package spt.csv; import java.text.ParseException;
import java.util.Comparator;
import java.util.Map; import spt.util.DateService;
import spt.util.PropertyConfig; /**
*每条记录是一个Map对象,按照每条记录中的'时间'的列进行排序.
*/
public class RecordDateComparator implements Comparator<Map<String, String>> { @Override
public int compare(Map<String, String> m1, Map<String, String> m2) {
try {
long l01 = DateService.getDate(m1.get(PropertyConfig.getProperty("NYR"))).getTime();
long l02 = DateService.getDate(m2.get(PropertyConfig.getProperty("NYR"))).getTime();
//long的范围和int的范围不同.
long diff = l01 - l02;
if(diff < 0)
return -1;
else if(diff > 0)
return 1;
return 0;
} catch (ParseException e) {
e.printStackTrace();
return 0;
}
} }6,在main类中:
package spt.csv; import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Random; import spt.util.PropertyConfig; /**
* 从1w多条记录中先选出8k条,然后在8k条记录中选出2k条,最后将2k条记录分成10组.
*/
public class ReadWriteDemo { /**
* @param args
*/
public static void main(String[] args) {
// if (args.length < 1)
// throw new NullPointerException("请指定文件路径");
System.out.println("执行中...执行过程请不要关闭此窗口!");
final int first_size = Integer.parseInt(PropertyConfig
.getProperty("first_size")); // 初次提取长度(8k).
final int second_size = Integer.parseInt(PropertyConfig
.getProperty("second_size")); // 初次提取(2k).
final int groupCount = Integer.parseInt(PropertyConfig
.getProperty("groupCount")); // 分组个数(10).
String file = PropertyConfig.getProperty("input_file"); // 源文件路径. List<String> fieldNames = null;
try {
fieldNames = initFields();
Reader csv = new Reader(file);
// 总记录.
List<Map<String, String>> totalList = csv.getResult(fieldNames);
// 初次提取的值(8k).
List<Map<String, String>> firstTaken = random(totalList, first_size);
// 再次提取的值(2k).
List<Map<String, String>> secondTaken = random(firstTaken,
second_size);
// 每组记录数(2百).
List<Map<String, String>> tmpTaken = secondTaken;
for (int i = 0; i < groupCount; i++) {
List<Map<String, String>> AGroupTaken = random(tmpTaken,
second_size / groupCount);
// 除去上次已经使用的元素.
tmpTaken.removeAll(AGroupTaken);
// 在当前目录上输出(并验证是否存在).
String outputFile = null;
// 如果文件已存在,则自动命名.
int fileCount = 0;
do {
outputFile = "result" + fileCount++ + ".csv";
} while (new File(outputFile).exists());
Writer writer = new Writer(outputFile);
// (集合)排序.
Collections.sort(AGroupTaken, new RecordDateComparator());
writer.write(fieldNames, AGroupTaken);
}
System.out.println("done!");
} catch (FileNotFoundException e) {
System.out.println("请指定正确的文件路径!");
// TODO Auto-generated catch block
e.printStackTrace();
}
} /**
* 随机产生新的列表(长度比原来小).
*
* @param originalList
* 输入列表.
* @param new_size
* 新列表的长度.
*/
public static List<Map<String, String>> random(
List<Map<String, String>> originalList, int new_size) {
if (new_size <= 0 || new_size > originalList.size())
throw new IndexOutOfBoundsException("新列表的长度错误!");
List<Map<String, String>> newList = new ArrayList<Map<String, String>>(
new_size);
// 标识是否已被提取.
boolean[] taken = new boolean[originalList.size()];
Random r = new Random();
Map<String, String> map = null; // 即将获取的元素.
int rIdx = 0;
for (int i = 0; i < new_size; i++) {
do {
rIdx = r.nextInt(new_size);
map = originalList.get(rIdx);
} while (taken[rIdx]); // 如果发现已经提取,则重复操作.
taken[rIdx] = true; // 标识已被提取.
newList.add(map);
} return newList;
} private static List<String> initFields() {
// 所有字段.
List<String> fieldNames = new ArrayList<String>(14);
fieldNames.add("id");
fieldNames.add("AJMC");
fieldNames.add("JYAQ");
fieldNames.add("AJLB");
fieldNames.add("AJFAB");
fieldNames.add("AJZT");
fieldNames.add("BASJ");
fieldNames.add("FXSJ");
fieldNames.add("FASJSX");
fieldNames.add("FASJXX");
fieldNames.add("AJBH");
fieldNames.add("ZBX");
fieldNames.add("ZBY");
fieldNames.add("NYR"); return fieldNames;
}
}7,用到的自定义工具类为:
package spt.util; import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date; /**
* 2015-2-27 提供日期转换的工具类.
*/
public class DateService {
// 定义称线程共享,而不是没调用一次就创建一个对象.
private static DateFormat formater = new SimpleDateFormat(PropertyConfig.getProperty("date_format")); /**
* 将字符串类型的日期转换为Date.
*
* @param strDate
* @return
* @throws ParseException
*/
public static Date getDate(String strDate) throws ParseException {
// 如果输入为空,则返回null.
if (Str.isEmpty(strDate))
return null;
return formater.parse(strDate);
} /**
* 将java.util.Date转换为java.sql.Date;用于诸如'PreparedStatement.setDate'方法.
*
* @param utilDate
* @return
*/
public static java.sql.Date getSQLDate(java.util.Date utilDate) {
if (utilDate == null)
return null;
return new java.sql.Date(utilDate.getTime());
} /**
* 将指定的日期转换为
*
* @param date
* @return
*/
public static String getDateStr(java.util.Date date) {
if (date == null)
return null;
return formater.format(date);
} /**
* 计算指定日期与今天的间隔,判断是否是需要日期. disDay表示与今天相隔天数,0:等于今天;1:明天;-1:昨天.
*
* @param anotherDate
* @param disDay
* @return
*/
public static boolean isSpecifiedDay(Date anotherDate, int disDay) {
if (anotherDate == null)
return false;
Calendar cNow = Calendar.getInstance();
cNow.setTime(new Date()); // 每调用一次,都是与当前时间做比较.
cNow.add(Calendar.DAY_OF_MONTH, disDay); Calendar cAnotherDate = Calendar.getInstance();
cAnotherDate.setTime(anotherDate); return cNow.get(Calendar.YEAR) == cAnotherDate.get(Calendar.YEAR)
&& cNow.get(Calendar.MONTH) == cAnotherDate.get(Calendar.MONTH)
&& cNow.get(Calendar.DAY_OF_MONTH) == cAnotherDate.get(Calendar.DAY_OF_MONTH);
}
}package spt.util; import java.io.IOException;
import java.net.URL;
import java.util.Properties; /**
* 2015-2-27
*/
public class PropertyConfig { /**
* @param key
* @return
*/
public static String getProperty(String key) {
Properties properties = getProperties();
return properties.getProperty(key);
} /**
* @param resources
* @return
*/
public static Properties getProperties() {
final String configFilePath = "raw/properties.properties";
URL url = PropertyConfig.class.getClassLoader().getResource(configFilePath);
Properties props = new Properties();
try {
props.load(url.openStream());
} catch (IOException e) {
e.printStackTrace();
return null;
}
return props;
}
}package spt.util; /**
*字符串工具类.
*/
public class Str {
/**
* 判断一个字符串是否有内容.
*
* @param str
* @return 如果不不为空,则返回true,否则返回false.
*/
public static boolean hasLength(String str) {
return !isEmpty(str);
} /**判断字符串是否为空.
* @param str
* @return
*/
public static boolean isEmpty(String str) {
return str == null || str.isEmpty();
}
}其中,配置文件"raw/properties.properties"是放置在src目录下.
java csv - 读写及其操作.的更多相关文章
- Java读写文本文件操作
package com.test; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; ...
- Java CSV操作(导出和导入)
Java CSV操作(导出和导入) CSV是逗号分隔文件(Comma Separated Values)的首字母英文缩写,是一种用来存储数据的纯文本格式,通常用于电子表格或数据库软件.在 CSV文件 ...
- java对excel文件内容读写修改操作
Read.java package domain; import java.io.FileInputStream; import java.io.InputStream; import jxl.Cel ...
- java中的IO操作
IO流是用来处理设备之间的数据传输,Java对数据的操作是通过流的方式进行,而操作流的对象都封装到java.io包中.根据操作数据的种类可以把IO流分为字节流(InputStream,OutputSt ...
- java对cookie的操作
java对cookie的操作比较简单,主要介绍下建立cookie和读取cookie,以及如何设定cookie的生命周期和cookie的路径问题. 建立一个无生命周期的cookie,即随着浏览器的关闭即 ...
- java StringBuffer读写文件
java StringBuffer读写文件 StringBuffer的优势 较String:String每更新一次就会new一个新的对象出来,更新次数上去之后,内存开销太大.而StringBuffer ...
- JAVA多线程读写文件范例
在写之前先声明,本文是基于之前在博客园网站上检索到的一份JAVA多线程读写文件的示例,我在写自己的程序时是在那位作者写的基础上做了改良,但已不记得原文的地址.如果有知情者,烦请帖出地址,我在此文上加入 ...
- Java中的文件操作(一)RandomAccessFile
今天,学到的是java中的文件操作. Java.IO.File Java中操作文件用到RandomAccessFile类,既可以读取文件内容,也可以向文件输出数据,但不同与普通输入/输出流的是Rand ...
- Java并发包——Atomic操作
Java并发包——Atomic操作 摘要:本文主要学习了Java并发包下的atomic包中有关原子操作的一些类. 部分内容来自以下博客: https://blog.csdn.net/qq_303796 ...
随机推荐
- C#实例:5个.net经典例子(窗体与界面设计)
实例001 带历史信息的菜单 实例说明 在开发图纸管理软件时,要求在菜单上记录用户最近打开的档案或图纸,以方便下次使用.如图1.1所示,单击“文件”菜单下的“打开文件”子菜单,打开需要查阅的图纸.下 ...
- 一起啃PRML - 1.2 Probability Theory 概率论
一起啃PRML - 1.2 Probability Theory @copyright 转载请注明出处 http://www.cnblogs.com/chxer/ A key concept in t ...
- 冒烟测试、α测试、Beta测试、性能测试
“冒烟测试”(也可称为showcase)这一术语描述的是在将代码更改嵌入到产品的源树中之前对这些更改进行验证的过程. 冒烟测试(smoke test)在测试中发现问题,找到了一个Bug,然后开发人员会 ...
- 进军es6(2)---解构赋值
本该两周之前就该总结的,但最近一直在忙校招实习的事,耽误了很久.目前依然在等待阿里HR面后的结果中...但愿好事多磨!在阿里的某轮面试中面试官问到了es6的掌握情况,说明es6真的是大势所趋,我们更需 ...
- 各个平台 如何安装 Ruby 和 RubyGems
原文地址:http://cloudfoundry-doc.csdn.net/frameworks/ruby/installing-ruby.html Last Updated: 2012-11-01 ...
- poj 2079 Triangle(旋转卡壳)
Triangle Time Limit: 3000MS Memory Limit: 30000K Total Submissions: 8917 Accepted: 2650 Descript ...
- Spark RDD/Core 编程 API入门系列之动手实战和调试Spark文件操作、动手实战操作搜狗日志文件、搜狗日志文件深入实战(二)
1.动手实战和调试Spark文件操作 这里,我以指定executor-memory参数的方式,启动spark-shell. 启动hadoop集群 spark@SparkSingleNode:/usr/ ...
- Yii rabc角色权限管理文章推荐
yii的这个rbac太通用,太灵活,有时候理解起来有困难.也是初学这个,推荐一个不错的文章:http://www.yiiframework.com/wiki/136/getting-to-unders ...
- MySQL数据库设计复习笔记及项目实战
最近手头上有3个项目开动,其他2个都是从底层开始的,一个已经开始了一段时间的了,在小城市小团队开发的条件下,都没有专门的DBA来做数据库的设计和维护,往往都是开发人员顶上,可是看了很多的数据库的设计, ...
- nyoj 119 士兵杀敌(三)【线段树区间最大值最小值差】
士兵杀敌(三) 时间限制:2000 ms | 内存限制:65535 KB 难度:5 描述 南将军统率着N个士兵,士兵分别编号为1~N,南将军经常爱拿某一段编号内杀敌数最高的人与杀敌数最低的人进 ...