目录
前言
开发过程中需要将千万级数据导出为文件,因excel对行数有限制,最终决定将文件定为TXT文件,TXT文件对行数近乎无限制。
一、文件写入的笔 —— PrintWriter
进行文件写入使用的是PrintWriter,具有自动行刷新的缓冲字符输出流,特点是可以按行写出字符串,并且可以自动行刷新。最开始使用的是指定文件和字符集的构造方法,但是测试时发现该构造方法每次打开文件时会清空现有数据,重新写入,无法以追加的方式写入文件,但是因为是千万级数据量的写入,必定是分次写入,最后改为指定输出流的方式,在输出流中指定文件写入方式为追加。
二、实现步骤
实现方法也不难,首先对JSONArray数组进行遍历,获取JSONObject对象,再对JSONObject进行遍历,存在键时,将其对应的值取出,进行格式化处理后,写入文件中。
1.文件判断
判断文件是否存在,不存在则创建:
File file = new File(fullPath);
File folder = new File(path);
if (!folder.exists() && !folder.isDirectory()) {
// 如果不存在,创建文件夹
folder.mkdirs();
}
if (!file.exists()) {
file.createNewFile();
}
2.读取数据
遍历JSONArray数组,获取JSONObject对象,再对JSONObject进行遍历,存在键时,将其对应的值取出,进行格式化处理后写入文件:
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
if (jsonObject.isEmpty()) {
break;
}
StringBuilder thisLine = new StringBuilder("");
for (Iterator<String> iterator = jsonObject.keySet().iterator(); iterator.hasNext(); ) {
// 遍历每个字段,并进行格式化处理
}
}
总结
文件写入总体来说还是很简单的,就是读取数据写入文件中,需要注意文件写入的方式、数据字段的格式化、何时进行文件写入、最后一定记得关闭流。
为方便大家使用,现将完整代码给出:
public boolean createTxtFile(JSONArray jsonArray, String path, String filename) {
// 标记文件生成是否成功
boolean flag = true;
try {
// 含文件名的全路径
String[] strings = {path, filename, ".txt"};
String fullPath = StrUtils.strSplice(strings);
File file = new File(fullPath);
File folder = new File(path);
if (!folder.exists() && !folder.isDirectory()) {
// 如果不存在,创建文件夹
folder.mkdirs();
}
if (!file.exists()) {
file.createNewFile();
}
// 格式化浮点数据
NumberFormat formatter = NumberFormat.getNumberInstance();
// 设置最大小数位为10
formatter.setMaximumFractionDigits(10);
// 格式化日期数据
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
// 遍历输出每行
PrintWriter pfp = new PrintWriter(new FileOutputStream(file, true));
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
if (jsonObject.isEmpty()) {
break;
}
StringBuilder thisLine = new StringBuilder("");
for (Iterator<String> iterator = jsonObject.keySet().iterator(); iterator.hasNext(); ) {
// 当前字段
String key = iterator.next();
Object obj = jsonObject.get(key);
// 格式化数据
String field = "";
if (null != obj) {
if (obj.getClass() == String.class) {
// 如果是字符串
field = (String) obj;
} else if (obj.getClass() == Double.class || obj.getClass() == Float.class) {
// 格式化浮点数,使浮点数不以科学计数法输出
field = formatter.format(obj);
} else if (obj.getClass() == Integer.class || obj.getClass() == Long.class
|| obj.getClass() == Short.class || obj.getClass() == Byte.class) { // 如果是整形
field += obj;
} else if (obj.getClass() == Date.class) {
// 如果是日期类型
field = sdf.format(obj);
}
} else {
// null时给一个空格占位
field = " ";
}
// 拼接所有字段为一行数据,用tab键分隔
// 不是最后一个元素
if (iterator.hasNext()) {
thisLine.append(field).append("\t");
} else {
// 是最后一个元素
thisLine.append(field);
}
}
pfp.print(thisLine.toString() + "\n");
}
pfp.close();
} catch (Exception e) {
flag = false;
logger.error("生成txt文件失败", e);
}
return flag;
}