1、IO概述- IO流概述及分类
1)、IO流:
I:Input(输入):数据从外部流向程序中。(外部:文件)
O:Ouput(输出):数据从程序流向外部。
流:线性的,有方向的
2)、作用:
可以“读”,“写”文件的内容,File类只能获取文件/目录的一些属性信息,但不能读写文件内容,只有IO流可以
3)、Java的IO流体系结构:
字节流:按字节读写文件,可以操作任何类型文件(纯文本,二进制…)
字符流:按字符读写文件,仅可以读写纯文本文件
输入流 | 输出流 |
---|---|
字节流 | 字节输入流InputStream |
字符流 | 字符输入流Reader |
2、字节流-一切皆字节
1)、一切皆为字节:任何文件(纯文本,二进制…)最终在磁盘上存储的都是“二进制”,Java处理这些二进制的最小单位就是“字节(8位)”
2)、“字节流”是Java中IO流中最基本的流,任何其他的流都是基于字节流的
3、字节流-字节输出流-父类OutputStream的输出方式
1)、java.io.OutputStream
(抽象类):字节输出流的父类;
2)、定义输出的方法:
public void close()
:关闭此输出流并释放与此流相关联的任何系统资源。public void flush()
:刷新此输出流并强制任何缓冲的输出字节被写出。public void write(byte[] b)
:输出一个字节数组public void write(byte[] b, int off, int len)
:输出字节数组的一部分(从索引为off处开始,往后len个数组元素)public abstract void write(int b)
:输出一个字节。
4、字节流-字节输出流-子类FileOutputStream的输出方法和追加写入及换行
1)、java.io.FileOutputStream
(子类):是文件输出流,用于将数据写出到文件。
2)、构造方法:
public FileOutputStream(File file)
:创建文件输出流以写入由指定的 File对象表示的文件。覆盖写public FileOutputStream(String name)
: 使用指定文件名构造一个输出流。覆盖写public FileOutputStream(File file, boolean append)
: 创建文件输出流以写入由指定的 File对象表示的文件。 追加写public FileOutputStream(String name, boolean append)
: 创建文件输出流以指定的名称写入文件。 追加写注意:
1)、Java中任何输出流,构造时文件都可以不存在,会自动创建一个空的文件。
2)、Java的IO流不要构造在一个存在的目录上,会运行异常;如果是不存在的目录,就会创建一个没有后缀名的文件
3)、操作同一个文件时,FileOutputStream使用覆盖写的构造方法会把原文件覆盖
3)、输出的方法:(没有特殊方法,都是从父类继承的)
write(byte[] b)
:输出一个字节数组(write(“字符串”.getBytes())),常用于输出字符串write(byte[] b, int off, int len)
:从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。(从off开始,写入往后len个字节数组元素)write(int b)
:输出一个字节。public static void main(String[] args) throws IOException { //1.FileOutputStream(String pathName) FileOutputStream out = new FileOutputStream("demo02.txt",true); //2.FileOutputStream(File file) // FileOutputStream out2 = new FileOutputStream(new File("demo02_2.txt")); //1.write(int b):输出一个字节 out.write(97); out.write(98); //2.write(byte[] byteArray):输出多个字节(一个byte[]数组) String s = "你好"; out.write(s.getBytes()); out.write("\r\n".getBytes());//换行 out.write("97".getBytes()); out.write("\r\n".getBytes());//换行 //3.write(byte[] byteArray,int off,int len): byte[] byteArray = {97, 98, 99, 100, 101}; //只需要输出:c,d,e out.write(byteArray,2,3); //关闭 out.close(); }
5、字节流-字节输入流-父类InputStream的读取方法
1)、java.io.InputStream
(抽象类):所有直接输出流的父类;
2)、读取的方法:
public void close()
:关闭此输入流并释放与此流相关联的任何系统资源。public abstract int read()
:读取一个字节。public int read(byte[] b)
:读取字节数组。(返回值是读到的字节数组长度)
6、字节流-字节输入流-子类FileInputStream的读取方法
1)、java.io.FileInputStream
(子类)是文件输入流,从文件中读取字节。
2)、构造方法:
FileInputStream(File file)
: 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。FileInputStream(String name)
: 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。注意:
1)、Java中所有的输入流构造时,文件必须存在,否则运行异常
2)、读取的方法是从父类继承的:
public int read()
:读取一个字节public int read(byte[] byteArray)
:读取一个字节数组public static void main(String[] args) throws IOException { FileInputStream in = new FileInputStream("demo03.txt"); //1.读取一个字节 /* int b = 0; while((b = in.read()) != -1) { System.out.println("读取的字节:" + b); System.out.println("转换为字符:" + (char) b); }*/ //2.读取一个字节数组 byte[] byteArray = new byte[3]; int len = 0; while((len = in.read(byteArray)) != -1) { System.out.println("返回值:" + len); System.out.println("数组内容:" + Arrays.toString(byteArray)); } in.close(); }
7、字节流-字节流练习-图片复制
public static void main(String[] args) throws IOException {
//1.构造一个到源文件的:输入流
FileInputStream in = new FileInputStream("d:\\douyu.exe");
//2.构造一个到目标文件的:输出流
FileOutputStream out = new FileOutputStream("e:\\douyu_copy2.exe");//创建一个空文件
//3.开始复制--慢
//1.一次读、写一个字节
/*int b = 0;
while ((b = in.read()) != -1) {
out.write(b);
}
*/
//2.一次读、写多个字节--快
byte[] byteArray = new byte[1024 * 8];
int len = 0;
while ((len = in.read(byteArray)) != -1) {
out.write(byteArray,0,len);
}
out.close();
in.close();
System.out.println("复制完毕!");
}
8、字符流-概述
1)、字符流:一次按一个字符读取,每个国家的字符占用的字节数是不同的,(UTF-8,汉字占用3个字节)
2)、各个国家使用的编码表不同,字符占用的字节数也就不同,如果都使用“字节流”读写就会很不方便,所以Java提供了一种专门操作纯文本文件的字符流
9、字符流-字符输出流-父类Writer的输出方法
1)、java.io.Writer
(抽象类):所有字符输出流的父类
2)、常用方法:
public abstract void close()
:关闭此输出流并释放与此流相关联的任何系统资源。(自带刷新和关闭流)public abstract void flush()
:刷新此输出流并强制任何缓冲的输出字符被写出。public void write(int c)
:输出一个字符public void write(char[] cbuf)
:输出一个字符数组public abstract void write(char[] b, int off, int len)
:输出字符数组的一部分public void write(String str)
:输出一个字符串
注意:在使用字符流输出字符和字符串后,字符流会创建一个缓存区,必须对缓存区进行刷新(flush()或close()),才会写入文件中
10、字符流-字符输出流-子类FileWriter类的使用
1)、java.io.FileWriter
(子类)
2)、构造方法:
FileWriter(File file)
: 创建一个新的 FileWriter,给定要读取的File对象。FileWriter(String fileName)
: 创建一个新的 FileWriter,给定要读取的文件的名称。FileWriter(String fileName,boolean append)
:构造一个FileWriter对象,给出一个带布尔值的文件名,表示是否附加写入数据FileWriter(File file,boolean append)
: 创建一个新的 FileWriter,给定要读取的File对象,布尔值表示时候附加写入数据public static void main(String[] args) throws IOException { FileWriter out = new FileWriter("demo06.txt");//覆盖写 // FileWriter out2 = new FileWriter("demo06.txt", true);//追加写 //1.writer(int c): out.write('你'); out.write('a'); //2.write(char[] chArray) out.write("你好".toCharArray()); char[] chArray = {'a','b','你','好','啊','恩'}; out.write(chArray); //3.write(char[] chArray,int off,int len): //只输出:好,啊,恩 out.write(chArray,3,3); //4.write(String s): out.write("呵呵"); out.write("\r\n"); //5.write(String s,int off,int len) String s = "我爱Java"; //要求输出:s中的Java out.write(s,2,4); //out.flush();//刷新缓存区 out.close();//flush() + close()(建议) }
11、字符流-字符输入流-父类Reader的读取的方法
1)、java.io.Reader
(抽象类)
2)、常用方法:
public void close()
:关闭此流并释放与此流相关联的任何系统资源。public int read()
: 读取一个字符,返回值:字符的编码public int read(char[] cbuf)
:读取一个字符数组,返回值:字符数量
12、字符流-字符输入流-子类-FileReader类的使用
1)、java.io.FileReader
(子类)
2)、构造方法:
FileReader(File file)
: 创建一个新的 FileReader ,给定要读取的File对象。FileReader(String fileName)
: 创建一个新的 FileReader ,给定要读取的文件的名称。public static void main(String[] args) throws IOException { File file = new File("demo07.txt"); if (!file.exists()) { file.createNewFile(); } FileReader in = new FileReader(file); //一次读取一个字符 /*int c = 0; while ((c = in.read()) != -1) { System.out.println("读取的字符:" + (char)c); }*/ //一次读取一个字符数组 char[] chArray = new char[2]; int len = 0; while ((len = in.read(chArray)) != -1) { System.out.println(chArray); } in.close(); }
13、IO异常处理-JDK7前的处理
public static void main(String[] args) {
FileReader in = null;
try {
in = new FileReader("demo07.txt");
//一次读取一个字符数组
char[] chArray = new char[2];
int len = 0;
while ((len = in.read(chArray)) != -1) {
System.out.println(chArray);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
14、IO异常处理-JDK7和JDK8的处理方式(开发常用)
public class Demo {
public static void main(String[] args) {
try (
//in对象不需要我们关闭,会自动关闭
FileReader in = new FileReader("demo07.txt");
) {
//一次读取一个字符数组
char[] chArray = new char[2];
int len = 0;
while ((len = in.read(chArray)) != -1) {
System.out.println(chArray);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
15、IO异常处理-JDK9改进的处理方式
public class Demo {
public static void main(String[] args) throws IOException {
//假设,这两个对象不是我们创建的,从其它地方获取的,但需要我们用完后关闭。
FileWriter out = new FileWriter("demo10.txt");
FileReader in = new FileReader("demo10_2.txt");
//写在try(...)中的对象,在用完后会自动关闭。
try (in; out) {
char[] chArray = new char[1024];
int len = 0;
while ((len = in.read(chArray)) != -1) {
out.write(chArray, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
16、属性集-Properties类概述
1)、java.util.Properties
(类):此类是一个Map集合
2)、此类中有俩个方法可以用于方便的读、写配置文件;
3)、配置文件:指软件运行过程中记录用户的一些设置信息的文件,这种配置文件在国际上有一个通用的格式:
名1 = 值;
名2 = 值;
这种格式与Map的键值对格式正好匹配,所以制作了一个Map集合,Properties方便读取配置文件
4)、Properties集合 –> 配置文件;配置文件 –>Properties集合
17、属性集-Properties类与流相关的方法介绍
Properties集合 –> 配置文件:store()方法
配置文件 –>Properties集合:load()方法
public class Demo {
public static void main(String[] args) throws IOException {
// write();
read();
}
private static void read() throws IOException {
Properties pro = new Properties();
FileReader in = new FileReader("demo11.txt");
pro.load(in);//一次性将配置文件中所有的键值对全部读取到集合中
in.close();
/*Set<Object> keys = pro.keySet();
for (Object o : keys) {
System.out.println(o + " = " + pro.get(o));
}*/
Set<String> keys = pro.stringPropertyNames();
for (String k : keys) {
System.out.println(k + " = " + pro.getProperty(k));
}
}
private static void write() throws IOException {
Properties pro = new Properties();
pro.setProperty("金币", "500000");//相当于:put(Object key,Object value)
pro.setProperty("钻石", "200000");
pro.setProperty("疲劳", "120");
pro.setProperty("血量", "100");
//存到配置文件
FileWriter out = new FileWriter("demo11.txt");
pro.store(out,"Hello");//将集合中所有的键值对一次性的写入到文件.
out.close();
}
}
复习
[ ] 能够说出IO流的分类和功能
1)、字节流:按字节读写文件,可以读写任何文件
2)、字符流:按字符读写文件,只能操作“纯文本”文件
[ ] 能够使用字节输出流写出数据到文件
FileOutputStream out = new FileOutputStream("demo01.txt"); out.write(97); out.close();
[ ] 能够使用字节输入流读取数据到程序
FileInputStream in = new FileInputStream("demo01.txt"); byte[] bytes = new byte[1024]; int len = 0; while((len = in.read(bytes))!=-1){ String s = new String(bytes,0,len); System.out.println("读取的内容:" + s); }
[ ] 能够理解读取数据read(byte[])方法的原理
[ ] 能够使用字节流完成文件的复制
[ ] 能够使用FileWirter写数据到文件
[ ] 能够说出FileWriter中关闭和刷新方法的区别
[ ] 能够使用FileWriter写数据的5个方法
[ ] 能够使用FileWriter写数据实现换行和追加写
[ ] 能够使用FileReader读数据
[ ] 能够使用FileReader读数据一次一个字符数组
[ ] 能够使用Properties的load方法加载文件中配置信息