I/O流
一、File类
1、构造的三种方法
java
File f1 = new File("//Users//wangminghao//Desktop//demo.txt");
System.out.println(f1);
File f2 = new File("//Users//wangminghao//Desktop","demo.txt");
System.out.println(f2);
File f3 = new File("//Users//wangminghao//Desktop");
File f4 = new File(f3,"demo.txt");
System.out.println(f4);
- 两个反斜线是为了转义
- 构造File类只是存储路径(抽象存在),不会创建相应的文件
2、File类的创建功能
- 不存在时创建新空文件:
public boolean createNewFile()
java
File f1 = new File("//Users//wangminghao//Desktop//demo.txt");
try {
System.out.println(f1.createNewFile());
} catch (IOException e) {
e.printStackTrace();
- 相对路径:默认与模块同一级别,在项目路径下
- 创建相应目录:
public boolean mkdir()
java
File f2 = new File("//Users//wangminghao//Desktop//demo");
System.out.println(f2.mkdir());
- 创建相应目录及其父目录:
public boolean mkdirs()
java
File f3 = new File("//Users//wangminghao//Desktop//demo1//demo2");
System.out.println(f3.mkdirs());
3、File类的删除方法
public boolean delete()
:删除空文件夹或文件
4、File类的判断与获取方法
- 判目录:
public boolean isDirectory()
- 判文件:
public boolean isFile()
- 判存在:
public boolean exists()
- 返回绝对路径:
public String getAbsolutePath()
- 返回(构建时的)路径:
public String getPath()
- 返回目录/文件名:
public String getName()
- 返回目录下文件/目录的数组:
public String[] list()
- 返回目录下文件/目录的File:
public File[] listFiles()
5、遍历目录
java
public class demo4 {
static File f = new File("//Users//wangminghao//Desktop");
static int i = 0;
public static void main(String[] args) {
dfs(f);
}
public static void dfs(File f){
File[] files = f.listFiles();
for (File file : files){
if(file.isFile()){
System.out.println( ++i + "." + file.getName() + ":" + file.getAbsoluteFile());
}else{
dfs(file);
}
}
}
}
二、I/O流
- IO:输入输出
- 流:数据传输
- 用途:处理设备间的数据传输
- 分类
- 流向
- 输入流:读数据
- 输出流:写数据
- 数据类型
- 字节流:其他格式
- 字符流:文本格式
- 流向
三、字节流
1、字节流抽象基类
- InputStream:输入流超类
- OutputStream:输出流超类
- 子类名特点:以基类名为后缀
2、字节流写数据
创建FileOutputStream --> 创建文件和指向文件的字节输出流对象
javaFileOutputStream fos = new FileOutputStream("...//demo.txt");
写入数据
- 写一个字节:
void write(int b)
- 写一个字节数组:
void write(byte[] b)
- 返回一个字符串的字节数组:
byte[] getBytes(StandardCharsets.UTF_8)
- 写一个字节数组的部分:
void write(byte[] b, int off, int len)
- off:偏移量,即索引位置
- 写一个字节:
释放资源
javafos.close(); // 放finally
补充:
- 换行
- win:\r\n
- linux:\n
- mac:\r
- 追加写入
public FileOutputStream(String name, boolean append)
- append = true:追加写入,默认为false
- 换行
java
FileOutputStream fos = null;
try {
fos = new FileOutputStream("//Users//wangminghao//Desktop//demo.txt");
fos.write("芭芭拉冲呀!".getBytes(StandardCharsets.UTF_8));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(fos != null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
3、字节流读数据
- 创建FileInputStream
FileInputStream fis = new FileInputStream("...//demo.txt");
读取数据
- 读一个字节:
int read()
--> 返回ascii码,到末尾返回-1
javaint by; while((by = fis.read()) != -1){ System.out.print(by); }
- 读一个字节数组:
int read(byte[] b)
javabyte[] bys = new byte[1024]; int len; while((len = fis.read(bys)) != -1){ System.out.print(new String(bys,0,len)); }
- 读一个字节数组的部分:
void write(byte[] b, int off, int len)
- off:偏移量,即索引位置
- 读一个字节:
4、字节缓冲流
- 作用:将数据写入缓冲区,一次性输出,提高效率 --> 字节缓冲流 + 一次读写一个字节数组:最快
- 字节缓冲输出流:
BufferedOutputstream(Outputstream out)
- 字节缓冲输入流:
BufferedInputstream(Inputstream in)
- 建议使用匿名对象
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("//Users//wangminghao//Desktop//demo.mp4"));
- 刷新流:
void flush()
--> 将缓冲区刷新到输入、输出流
四、字符流
1、字符流概述
- 字符流 = 字节流 + 编码表
- 出现的的原因:
- 字节读取文本数据文件,汉字在不同编码下占用的字节数不同
- 中文第一个数字是负数
- GBK:2字节
- UTF-8:3字节
2、字符串的编解码问题
(1)编码
byte[] getBytes()
:默认编码byte[] getBytes(String charsetName)
:指定编码
(2)解码
String(byte[] bytes)
:默认解码String(byte[] bytes, String charsetName)
:指定解码
(3)字符流抽象基类
- 输入流Reader:InputStreamReader:字节 --> 字符
InputStreamReader isr = new InputStreamReader(new FileInputStream("D:\\demo")[, "UTF-8"]);
- 输出流Writer:OutputStreamWriter:字符 --> 字节
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\demo")[, "UTF-8"]);
3、字符流读写数据
字符流写数据
- 写一个字符:
void write(int c)
- 写一个字符数组:
void write(char[] cbuf)
- 写部分字符数组:
void write(char[] cbuf, int off, int len)
- 写一个字符串:
void write(String s)
- 写部分字符串:
void write(String s, int off, int len)
- 刷新流:
void flush()
--> 除了字节流,其内部有缓冲区,需要刷新
字符流读数据
- 读一个字符:
int read()
- 读一个字符数组:
int read(char[] cbuf)
4、字符流子类
- FileReader:
FileReader(String fileName)
- FileWriter:
FileWriter(String fileName)
- 用途:
- 用于替代OutputStreamReader/InputStreamWriter
- 只能用默认字符集
5、字符缓冲流
- BufferedReader
- 构造方法:
BufferedReader(Reader in)
- 写一个换行:
void newLine()
- 构造方法:
- BufferedWriter
- 构造方法:
BufferedReader(Writer out)
- 读一行字符串:
public String readLine()
- 不包括终止字符
- 流的结尾返回null
- 构造方法:
java
String line;
while((line = br.readLine()) != null){
System.out.println(line);
}
6、异常处理
java
// 定义
try(定义流操作){
异常代码;
}catch{
异常处理代码;
}
// 实例
try (FileInputStream fis = new FileInputStream("D:\\demo1/txt");
FileOutputStream fos = new FileOutputStream("D:\\demo2.txt")) {
int r = fis.read();
fos.write(96);
} catch (IOException e) {
e.printStackTrace();
}
节省了释放资源于判断空指针异常的操作
五、特殊操作流
1、标准输入输出流
System类的两个静态成员变量
- 标准输入流:
public static final InputStream in
- 构造:
InputStream is = System.in
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
- 包装类Scanner:
Scanner sc = new Scanner(System.in);
- 构造:
- 标准输出流:
public static final OutputStream out
- System.out的本质是一个字节输出流
System.out.println(...);
System.out.print(...);
System.out.printf(...);
2、打印流
分类
- 字节打印流:
PrintStream(String fileName[, boolean autoFlush])
- 字符打印流:
PrintWriter(String fileName[, boolean autoFlush])
- autoFlush:每次print后自动刷新流,默认为false
特有方法
(不转码,所见即所得)
print
println
特点
- 只负输出数据,不负责读取
- 特有方法输出不转码,所见即所得
3、对象序列化流
概述
- 对象序列化:保存对象文件
- 对象反序列化:读取对象文件
对象序列化流:ObjectOutputStream
- 构造:
ObjectOutputStream(OutputStream out)
- 写入对象:
void writeObject(Object obj)
- 对象需要实现
Serializable
标记接口
对象反序列化流:ObjectInputStream
- 构造:
ObjectOutputStream(InputStream in)
- 读取对象:
Object readObject()
serialVersionUID
- 用于验证序列化和反序列化时,是否使用了同一个类
- 可以子类重写:
private static final long serialVersionUID = 42L;
transient关键词
使成员变量不参与序列化
4、Properties
- 作为Map集合的使用
java
Properties prop = new Properties();
prop.put("wmh","wjh");
for (Object key : prop.keySet()) {
System.out.println(key + "," + prop.get(key));
}
- 作为Map集合的特有方法
Object setProperty(String key, String value)
:put集合的值String getProperty(String key)
:查键值(不存在返回null)Set<String> stringPropertyNames()
:返回键集
- Properties与I/O流结合
- 字节流读取:
void load(InputStream inStream)
- 字符流读取:
void load(Reader reader)
- 字节流写入:
void store(OutputStream out, String comments)
- 字符流写入:
void store(Writer writer, String comments)
- comments:描述信息,不描述写null
- 字节流读取: