目录

​三,IO​

​1,java.io.File​

​1.1 常用构造方法​

​1.2 其他常用方法​

​1.3 字段​

​2,文件遍历案例​

​3,文件过滤器​

​应用实例​

​改进​

​4,相对与绝对路径​

​5,流概述​

​6,java.io.OutputStream​

​7,java.io.FileOutputStream​

​8,java.io.FileInputStream​

​8.1 常用方法​

​8.2 常见子类——FileInputStream​

​9,文件加密和解密工具​

​10,字节流读取文字​

​11,字符输出​

​12,字符读取​

​13,flush刷新管道​

​14,字节转换字符流​

​15,Print与BufferedReader​

​15.1 打印流​

​15.2 缓存读取流​

​16,收集异常日志​

​17,properties​

​17.1 概述​

​17.2 常用方法​

​18,序列化技术​

​18.1 概述​

​18.2 序列化​

​18.3 反序列化​

​19,try-with-resources​

​19.1 原因​

​19.2 解决方法​


三,IO

1,java.io.File

1.1 常用构造方法

1,构造方法声明


2,File(String pathname)


3,File(File parent, String child)


4,File(String parent, String child)


1.2 其他常用方法

03-Java核心类库_IO_IO

03-Java核心类库_IO_java_02

03-Java核心类库_IO_Java核心类库_03

03-Java核心类库_IO_Java开发工程师_04

03-Java核心类库_IO_Java核心类库_05

03-Java核心类库_IO_IO_06

03-Java核心类库_IO_IO_07

03-Java核心类库_IO_java_08

1.3 字段

不同操作系统路径分隔符可能不同,"//"不会适用于所有操作系统

03-Java核心类库_IO_IO_09

03-Java核心类库_IO_IO_10

2,文件遍历案例

package zuoye;

import java.io.File;


public class Demo4 {
public static void main(String[] args) {
File e = new File("e://");
File[] files = e.listFiles(); // 获得E盘下所有文件
listFile(files); // 调用遍历的方法

}

public static void listFile(File[] files){
if(files!=null&&files.length>0){ // 文件存在且不为空
for (File file:files) {
if(file.isFile()){ // 是文件
if(file.getName().endsWith(".avi")){ // 选择avi后缀的
if(file.length()>100*1024*1024) // 文件大小大于100M
System.out.println("找到了一个avi文件"+file.getAbsolutePath());
}
}else { // 是文件夹
File[] files2 = file.listFiles();
listFile(files2); // 递归
}
}
}

}
}

3,文件过滤器


应用实例

package com.kaikeba;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;

public class Demo1 {
public static void main(String[] args) throws IOException {
File e = new File("d://");
listFiles(e);
}
public static void listFiles(File file){ // 自定义的方法
if(file != null && file.length() != 0){ // 文件存在且不为空
// 1,创建一个过滤器,并描述规则
FileFilter filter = new AVIFileFilter();
// 2,通过文件获取子文件夹
File [] files = file.listFiles(filter); // 对象的方法
// 3,递归遍历所有文件
for(File f : files) {
if(f.isDirectory()) {
listFiles(f);
}else {
System.out.println("发现一个txt文件:" + f.getAbsolutePath());
}
}
}
}
static class AVIFileFilter implements FileFilter{ // 为实现过滤器接口 需要定义一个类 这里为静态内部类
@Override
public boolean accept(File pathname) {
// 只保留txt文件和文件夹
if(pathname.getName().endsWith(".txt") || pathname.isDirectory()) {
return true;
}
return false;
}
}
}

改进

用匿名内部类实现FileFilter接口,并直接作为参数,调用listFiles获得筛选过后的文件

package com.kaikeba;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;

public class Demo1 {
public static void main(String[] args) throws IOException {
File e = new File("d://");
listFiles(e);
}
public static void listFiles(File file){
if(file != null && file.length() != 0){ // 文件存在且不为空
File [] files = file.listFiles(new FileFilter() { // 通过匿名内部类作为参数的方法 实现过滤
@Override
public boolean accept(File pathname) {
// 只保留txt文件和文件夹
if(pathname.getName().endsWith(".txt") || pathname.isDirectory()) {
return true;
}
return false;
}
});
// 递归遍历所有文件
for(File f : files) {
if(f.isDirectory()) {
listFiles(f);
}else {
System.out.println("发现一个txt文件:" + f.getAbsolutePath());
}
}
}
}
}

4,相对与绝对路径

绝对路径:以盘符开始,是一个完整的路径,例如c://a.txt
相对路径:java中是相对于项目目录路径,这是一个不完整的路径,在Java开发中很常用    例如  a.txt

03-Java核心类库_IO_java_11

5,流概述

package com.java.demo;


import java.io.*;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;

/**
* @author liweijie
*/
public class Demo {
/**
* IO流概述
* 可以将这种数据传输操作,看做一种数据的流动 , 按照流动的方向分为输入Input和输出Output
* Java中的IO操作主要指的是 java.io包下的一些常用类的使用. 通过这些常用类对数据进行读取(输入Input) 和 写出(输出Output)
*
* IO流的分类:
* 按照流的方向来分,可以分为:输入流和输出流.
* 按照流动的数据类型来分,可以分为:字节流和字符流
*
* 字节流:(顶级父类)
* - 输入流 : InputStream
* - 输出流 : OutputStream
* 字符流:(顶级父类)
* - 输入流 : Reader
* - 输出流 : Writer
*
*
* 一切皆字节:
* 计算机中的任何数据(文本,图片,视频,音乐等等)都是以二进制的形式存储的.
* 在数据传输时 也都是以二进制的形式存储的.
* 后续学习的任何流 , 在传输时底层都是二进制.
* @param args
*/
public static void main(String[] args) throws FileNotFoundException {


}

}

6,java.io.OutputStream

     *      一切皆字节:
     *      计算机中的任何数据(文本,图片,视频,音乐等等)都是以二进制的形式存储的.
     *      在数据传输时 也都是以二进制的形式存储的.
     *      后续学习的任何流 , 在传输时底层都是二进制.

OutputStream是抽象类

03-Java核心类库_IO_Java核心类库_12

03-Java核心类库_IO_Java开发工程师_13

注意:

写完一定要关闭close;

03-Java核心类库_IO_Java核心类库_14

7,java.io.FileOutputStream

03-Java核心类库_IO_Java开发工程师_15

03-Java核心类库_IO_java_16

其中append为true则表示,在文件末尾添加数据,否则表示重新写入数据

package zuoye;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;


public class Demo6 {
public static void main(String[] args) throws IOException {
//OutputStream
FileOutputStream fos = new FileOutputStream("c://a.txt"); // 没有添加append参数,表示默认false 即覆盖原数据
byte[] bytes = {65,66,67,68,69};
fos.write(bytes);
fos.close(); //写在哪在哪关闭
System.out.println("已经写出");

}
}

通过字符串+getBytes函数,获得字节数组:

03-Java核心类库_IO_Java核心类库_17

8,java.io.FileInputStream

8.1 常用方法

03-Java核心类库_IO_Java开发工程师_18

03-Java核心类库_IO_Java开发工程师_19

8.2 常见子类——FileInputStream

1)构造方法

03-Java核心类库_IO_Java核心类库_20

2)read()方法

03-Java核心类库_IO_IO_21

3)read(byte[] b)

注:代码中漏掉了fis.close(),这种错误一定要避免!!!

03-Java核心类库_IO_Java核心类库_22

改进方法(记录读取到的字节数)

03-Java核心类库_IO_java_23

9,文件加密和解密工具

示例代码

package com.kaikeba;

import java.io.*;
import java.util.Scanner;

public class Demo1 {
public static void main(String[] args) throws IOException {
System.out.println("请输入文件路径名:");
Scanner input = new Scanner(System.in);
String s = input.nextLine();
File oldFile = new File(s);
File newFile = new File(oldFile.getParent() + "_new_File_" + oldFile.getName());
FileInputStream fis = new FileInputStream(oldFile);
FileOutputStream fos = new FileOutputStream(newFile);
while (true) {
byte b = (byte) fis.read();
if(b == -1) {
break;
}
fos.write(b ^ 10);// 加密(一个数异或两次,还是本身)
}
fis.close();
fos.close();
System.out.println("加密/解密结束");
}

}

加密(新文件的命名方式修改了,但截图中并没有纠正过来)

03-Java核心类库_IO_Java开发工程师_24

03-Java核心类库_IO_java_25

再次运行程序进行解密(正确修改)

03-Java核心类库_IO_Java核心类库_26

10,字节流读取文字

由于工程使用的是UTF-8字符编码,所以在读取工程中的文本文件时,不会出现乱码

03-Java核心类库_IO_Java核心类库_27

03-Java核心类库_IO_Java开发工程师_28

03-Java核心类库_IO_Java开发工程师_29

由于提前限定了一次读取的字节数为10,所以出现了读取不到一个完整汉字的情况,因而出现乱码。但是UTF-8使用动态编码表,由于提前不知道每个字符需要多少字节,所以此方法不行。

所以下面引入了字符流,用来解决读取半字的问题

11,字符输出

字符流用来操作文字,而字节流可以操作任何文件,所以字节流更加常用。

03-Java核心类库_IO_IO_30

03-Java核心类库_IO_java_31

注意:

决定是否在原文件基础上追加的,是声明字符流对象是的append属性(为true则是追加模式);

append与write在实际实现上,没有区别,但是append会返回Writer对象;

03-Java核心类库_IO_IO_32

append方法的返回值(Writer类型)可以强转为该对象(FileWriter类型),所以可以继续调用append,因而称为“追加”;

03-Java核心类库_IO_Java开发工程师_33

12,字符读取

基本使用方法同字节流。

03-Java核心类库_IO_Java开发工程师_34

03-Java核心类库_IO_Java开发工程师_35

13,flush刷新管道

字符输出时,以字符为单位,但计算机中都是以字节为单位。当一个字符占用多个字节时,字符输入流未读取单个字符全部字节之前,会将已读取字节放入缓存;

字符输出流fw.flush()会将缓存中字符强制写入到文件中,fw.close()也会有此效果;

如果不执行的话,就不会将字符写入文件中,如图:

03-Java核心类库_IO_Java开发工程师_36

03-Java核心类库_IO_Java核心类库_37

14,字节转换字符流

转换流。将字节流装饰为字符流:使用了装饰者模式;

为什么要使用字节流+转换流?直接字符流不香吗?:由于平常使用时,可能获取的是字节流,所以才有这种转换方式

03-Java核心类库_IO_Java核心类库_38

15,Print与BufferedReader

15.1 打印流

1)打印字节流与打印字符流

打印字节流

03-Java核心类库_IO_Java核心类库_39

打印字符流(记得flush或close)

03-Java核心类库_IO_Java开发工程师_40

打印字节流和打印字符流在使用上差别不大,但字符流需要调用flush,否则不会写入到文件中;

2)字节流转换为打印流

03-Java核心类库_IO_IO_41

15.2 缓存读取流

将字符输入流转换为带有缓存可以一次读取一行的缓存字符读取流

字节流-》字符流-》缓存读取流

03-Java核心类库_IO_IO_42

当读取到末尾时,会返回null

 

16,收集异常日志

普通的异常控制台显示

03-Java核心类库_IO_Java开发工程师_43

可以将异常信息保存在txt文档中,并加上日期,便于后期核查

03-Java核心类库_IO_IO_44

17,properties

17.1 概述

03-Java核心类库_IO_Java核心类库_45

properties继承HashTable属于Map集合(键值对),但其扩展部分含有IO相关用法(配置文件)

17.2 常用方法

1)store方法:将properties对象内容写入字节流/字符流所指的文件中

03-Java核心类库_IO_Java开发工程师_46

03-Java核心类库_IO_java_47

2)load方法:将字节流/字符流指向的文件内容加载到properties对象中

03-Java核心类库_IO_Java核心类库_48

03-Java核心类库_IO_Java核心类库_49

3)get与getProperty

03-Java核心类库_IO_Java开发工程师_50

get返回Object对象,getProperty返回字符串。

03-Java核心类库_IO_Java核心类库_51

18,序列化技术

18.1 概述

由于垃圾回收机制的存在,一些属性或对象,在程序关闭之后,便消失,无法重复利用,所以有人在想能不能将把对象完整的存储在文件中,使用时再取出来,即对象在内存中存储的字符序列(看上去像是乱码);

将文件中的对象读取到程序中来,就是反序列化;

虽然序列化很方便,但是却十分容易产生Bug(占Bug总数将近三分之一),所以Java官方提出近几年将要进行整改,建议大家不要使用此方法;(了解下也是有必要的)

18.2 序列化

Java官方规定,所有对象均不能序列化,想要序列化,需添加标记

03-Java核心类库_IO_Java开发工程师_52

添加标记:实现接口Serializable。添加代码后没有任何飘红,即说明不需要实现任何方法,因此这个接口被称为标记接口。

03-Java核心类库_IO_Java开发工程师_53

18.3 反序列化

03-Java核心类库_IO_Java核心类库_54

19,try-with-resources

19.1 原因

1)在文件流使用完毕后需要关闭

03-Java核心类库_IO_Java开发工程师_55

2)为了使close一定被执行,需要将其放在finally中

03-Java核心类库_IO_IO_56

3)所以需要将fr提到try之前,但仍可能产生空指针异常

03-Java核心类库_IO_IO_57

4)继续try-catch处理

03-Java核心类库_IO_IO_58

5)综上,这么多步骤就是为了读入一个字符

19.2 解决方法

1)jdk1.7之前:在try中new的对象会在try或catch块执行完毕后执行close。但要求,能使用此方法的类必须实现Closeable或AutoCloseable两个接口

03-Java核心类库_IO_Java核心类库_59

2)但是,如果后面还有代码块需要用到try中的对象时,就显得不方便了。JDK9进行了改进

03-Java核心类库_IO_IO_60