0%

Java 文件高级技术(一):常见文件类型处理

1. 字节流和字符流都是以流的方式读写文件,流的限制有

  • 要么读,要么写,不能同时读和写
  • 不能随机读写,只能从头读到尾,且不能重复读。虽然通过缓冲可以实现部分重读,但是有限制

2. RandomAccessFile 的作用

  • RandomAccessFile 没有上面两个限制,既可以读,也可以写,还可以随机读写
  • 是一个更接近操作系统 API 的封装类

3. 内存映射文件的作用

  • 内存映射文件可以高效处理非常大的文件
  • 可以被多个不同的应用程序共享
  • 特别适合用于不同应用程序之间的通信

4. 流读写文件的限制

  • 使用流读写文件时,需要逐个处理对象中的每个字段,处理起来较为麻烦
  • 需要考虑很多空格特殊字符等小细节

5. Java 中经常处理的常见的文件类型有哪些

  • 属性文件:属性文件是常见的配置文件,用于在不改变代码的情况下改变程序的行为
  • CSV:CSV 是 Comma-Separated Values 的缩写,表示逗号分隔值,是一种非常常见的文件类型。大部分日志文件都是 CSV,CSV 也经常用于交换表格类型的数据。CSV 看上去很简单,但处理的复杂性经常被低估
  • Excel:在编程中,经常需要将表格类型的数据导出为 Excel 格式,以方便用户查看,也经常需要接受 Excel 类型的文件作为输入以批量导入数据
  • HTML:所有网页都是 HTML 格式,我们经常需要分析 HTML 网页,以从中提取感兴趣的信息
  • 压缩文件:压缩文件有多种格式,也有很多压缩工具,大部分情况下,我们可以借助工具而不需要自己写程序处理压缩文件,但某些情况下,需要自己编程压缩文件或解压缩文件

6. 使用类 java.util.Properties 读取配置文件 config.properties

1
2
3
4
db.host = 192.168.10.100
db.port = 3306
db.username = zhangsan
db.password = mima1234
1
2
3
4
5
6
Properties prop = new Properties();
prop.load(new FileInputStream("config.properties")); //load() 用于从流中加载属性
String host = prop.getProperty("db.host");

//getProperty() 用于获取属性,可以提供一个默认值,如果没有找到配置的值,就返回默认值
int port = Integer.valueOf(prop.getProperty("db.port", "3306"));

7. 使用类 Properties 处理属性文件的好处和限制分别是

  • 可以自动处理空格,分隔符 = 前后的空格会被自动忽略
  • 可以自动忽略空行
  • 可以添加注释,以字符 #! 开头的行会被视为注释,进行忽略
  • 限制:不能直接处理中文,在配置文件中,所有非 ASCII 字符需要使用 Unicode 编码

8. CSV 文件是指

  • CSV 是 Comma-Separated Values 的缩写,表示逗号分隔值
  • 一般而言,一行表示一条记录,一条记录包含多个字段,字段之间用逗号分隔
  • 一般而言,分隔符不一定是逗号,可能是其他字符,如 tab 符 \t、冒号 :、分号 ;
  • 程序中的各种日志文件通常是 CSV 文件,在导入导出表格类型的数据时,CSV 也是常用的一种格式

9. CSV 文件处理的复杂性

  • 字段内容中包含分隔符
  • 字段内容中包含换行符
  • 怎么表示 null
  • 空行和字段之间的空格怎么处理
  • 怎么表示注释

10. 使用第三方类库 Apache Commons CSV 读取 CSV 文件的示例(CSV 1.4 版本)

1
2
3
4
5
6
7
8
9
10
11
12
13
CSVFormat format = CSVFormat.newFormat(';').withQuote('"').withNullString("N/A").withIgnoreSurroundingSpaces(true);
Reader reader = new FileReader("student.csv");
try {
for(CSVRecord record : format.parse(reader)) {
int fieldNum = record.size();
for(int i=0; i<fieldNum; i++) {
System.out.print(record.get(i) + " ");
}
System.out.println();
}
} finally {
reader.close();
}

11. 使用第三方类库 Apache Commons CSV 写 CSV 文件

1
2
3
4
5
6
7
8
CSVPrinter out = new CSVPrinter(new FileWriter("student.csv), CSVFormat.DEFAULT);
out.printRecord("老隋", 18, "看电影,看书,听音乐");
out.printRecord("小隋", 16, "乐高;赛车;");
out.close();

//输出文件 student.csv 中的内容为:
“老隋”, 18, “看电影,看书,听音乐”
“小隋”, 16, “乐高;赛车;”

12. Java 中怎样处理 Excel 文件

  • Excel 主要有两种格式,扩展名分别为 .xls.xlsx。.xlsx 是 Office 2007 以后的 Excel 文件的默认扩展名
  • Java 中处理 Excel 文件及其他微软文档广泛使用 POI 类库

13. 保存学生列表到 student.xls(POI 3.15 版本)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//Workbook: 表示一个 Excel 文件对象,它是一个接口,有两个主要类 HSSFWorkbook 和 XSSFWorkbook,前者对应 .xls 格式,后者对应 .xlsx 格式
//Sheet: 表示一个工作表
//Row: 表示一行
//Cell: 表示一个单元格
public static void saveAsExcel(List<Student> list) throws IOException {
Workbook wb = new HSSFWorkbook();
Sheet sheet = wb.createSheet();
for(int i=0; i<list.size(); i++) {
Student student = list.get(i);
Row row = sheet.createRow(i);
row.createCell(0).setCellValue(student.getName());
row.createCell(1).setCellValue(student.getAge());
row.createCell(2).setCellValue(student.getScore());
}
OutputStream out = new FileOutputStream("student.xls);
wb.write(out);
out.close();
wb.close();
}

//如果要保存为 .xlsx 格式,只需要替换第一行为:
Workbook wb = new XSSFWorkbook();

14. 使用 POI 解析 Excel 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static List<Student> readAsExcel() throws Exception {
Workbook wb = WorkbookFactory.create(new File("student.xls"));
List<Student> list = new ArrayList<Student> ();
for(Sheet sheet : wb) {
for(Row row : sheet) {
String name = row.getCell(0).getStringCellValue();
int age = (int) row.getCell(1).getNumericCellValue();
double score = row.getCell(2).getNumericCelValue();
list.add(new Student(name, age, score));
}
}
wb.close();
return list;
}

15. 使用 HTML 分析器 jsoup 分析网址:http://www.cnblogs.com/swiftma/p/5631311.html 的 HTML 代码,抽取网页主题内容中每篇文章的标题和链接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Document doc = Jsoup.parse(new File("articles.html"), "UTF-8);
Elements elements = doc.select("#cnblogs_post_body p a");
for(Element e : elements) {
String title = e.text();
String href = e.attr("href");
System.out.println(title + ", " + href);
}

//输出为(部分):
计算机程序的思维逻辑(1)- 数据和变量,http://www.cnblogs.com/swiftma/p/5396551.html
计算机程序的思维逻辑(2)- 赋值,http://www.cnblogs.com/swiftma/p/5399315.html

//jsoup 也可以直接连接 URL 进行分析,比如,上面代码的第一行可以替换为:
String url = "http://www.cnblogs.com/swifma/p/5631311.html";
Document doc = Jsoup.connect(url).get();

16. Java 对压缩文件的支持

  • 压缩文件有多种格式,Java SDK 支持两种:gzip 和 zip

  • gzip 只能压缩一个文件,zip 可以压缩多个文件

  • 对于 gzip

    • java.util.zip.GZIPOutputStreamjava.util.zip.GZIPInputStream 分别是 OutputStreamInputStream 的子类,都是装饰类
    • GZIPOutputStream 加到已有的流上,就可以是实现压缩;GZIPInputStream 加到已有的流上,就可以实现解压缩
  • 对于 zip

    • java.util.zip.ZipOutputStreamjava.util.zip.ZipInputStream 也分别是 OutputStreamInputStream 的子类,也都是装饰类
    • 使用起来比 gzip 要麻烦些

17. 写一个压缩一个文件的 Demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static void gzip(String fileName) throws IOException {
InputStream in = null;
String gzipFileName = fileName + ".gz";
OutputStream out = null;
try {
in = new BufferedInputStream(new FileInputStream(fileName));
out = new GZIPOutputStream(new BufferedOutputStream(new FileOutputStream(gzipFileName)));
copy(in, out); //复制输入流的内容到输出流
} finally {
if(out != null) {
out.close();
}
if(in != null) {
in.close();
}
}
}

18. 写一个解压一个文件的 Demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static void gUnzip(String gzipFileName, String unzipFileName) throws IOException {
InputStream in = null;
OutputStream out = null;
try {
in = new GZIPInputStream(new BufferedInputStream(new FileInputStream(gzipFileName)));
out = new BufferedOutputStream(new FileOutputStream(unzipFileName));
copy(in, out);
} finally {
if(out != null) {
out.close();
}
if(in != null) {
in.close();
}
}
}
-------------------- 本文结束感谢您的阅读 --------------------