目录
一、IO流的概述
1.什么是IO流
生活中,你肯定经历过这样的场景。当你编辑一个文本文件,忘记了ctrl+s ,可能文件就白白编辑了。当你电脑上插入一个U盘,可以把一个视频,拷贝到你的电脑硬盘里。那么数据都是在哪些设备上的呢?键盘、内存、硬盘、外接设备等等。
我们把这种数据的传输,可以看做是一种数据的流动,按照流动的方向,以内存为基准,分为输入input 和输出output ,即流向内存是输入流,流出内存的输出流。
Java中I/O操作主要是指使用java.io 包下的内容,进行输入、输出操作。输入也叫做读取数据,输出也叫做作写出数据。
2.IO流的分类
根据数据的流向分为:输入流和输出流。
输入流 :把数据从其他设备上读取到内存中的流。
输出流 :把数据从内存 中写出到其他设备上的流。
格局数据的类型分为:字节流和字符流。
字节流 :以字节为单位,读写数据的流。
字符流 :以字符为单位,读写数据的流。
3.Java中IO的四大类
二、字节流
1.面向对象和IO流
面向对象:万物皆对象
IO流:一切皆字节
2.字节输出流
java.io.OutputStream 抽象类是表示字节输出流的所有类的超类,将指定的字节信息写出到目的地。
public void close() :关闭此输出流并释放与此流相关联的任何系统资源。
public void write(byte[] b) :将 b.length字节从指定的字节数组写入此输出流。
public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。
public abstract void write(int b) :将指定的字节输出流。
public void flush() :刷新此输出流并强制任何缓冲的输出字节被写出。(字节流中此方法为空,没用)
3.FileOutputStream类的使用
(1)构造方法
public FileOutputStream(File file) :创建文件输出流以写入由指定的 File对象表示的文件。
public FileOutputStream(String name) : 创建文件输出流以指定的名称写入文件。
(2)写字节数据的三种方式
①写出字节: write(int b)
②写出字节数组: write(byte[] b)
③写出指定长度字节数组: write(byte[] b, int off, int len) ,每次写出从off索引开始,len个字节
(3)如何追加续写
public FileOutputStream(File file, boolean append)
public FileOutputStream(String name, boolean append)
这两个构造方法,参数中都需要传入一个boolean类型的值, true 表示追加数据, false 表示清空原有数据。这样创建的输出流对象,就可以指定是否追加续写了。
(4)换行符
Windows系统里,每行结尾是 回车+换行 ,即\r\n ;
Unix/Linux系统里,每行结尾只有 换行 ,即\n ;
Mac系统里,每行结尾是 回车 ,即\r 。从 Mac OS X开始与Linux统一。
4.字节输入流
java.io.InputStream 抽象类是表示字节输入流的所有类的超类,可以读取字节信息到内存中。
public void close() :关闭此输入流并释放与此流相关联的任何系统资源。
public abstract int read() : 从输入流读取数据的下一个字节。
public int read(byte[] b) : 从输入流中读取一些字节数,并将它们存储到字节数组 b中 。
5.FileInputStream类的使用
(1)构造方法
FileInputStream(File file) : 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。
FileInputStream(String name) : 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件
系统中的路径名 name命名。
(2)读取字节数据的两种方式
①读取字节: read()
// 使用文件名称创建流对象
FileInputStream fis = new FileInputStream("read.txt");
// 定义变量,保存数据
int b ;
// 循环读取
while ((b = fis.read())!=‐1) {
System.out.println((char)b);
}
// 关闭资源
fis.close();
②使用字节数组读取: read(byte[] b)
// 使用文件名称创建流对象.
FileInputStream fis = new FileInputStream("read.txt");
// 定义变量,作为有效个数
int len ;
// 定义字节数组,作为装字节数据的容器
byte[] b = new byte[1024];
// 循环读取
while (( len= fis.read(b))!=‐1) {
// 每次读取后,把数组变成字符串打印
System.out.println(new String(b,0,9len));
}
// 关闭资源
fis.close();
6.字节流练习:复制图片
try (BufferedInputStream bis = new BufferedInputStream
(new FileInputStream("day08_File类、递归/timg1.jpg"));
BufferedOutputStream bos = new BufferedOutputStream
(new FileOutputStream("day08_File类、递归/timg4.jpg"))) {
byte[] bys = new byte[1024];
int len = 0;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
三、字符流
1.字符输入流
java.io.Reader 抽象类是表示用于读取字符流的所有类的超类,可以读取字节信息到内存中。
public void close() :关闭此流并释放与此流相关联的任何系统资源。
public int read() : 从输入流读取一个字符。
public int read(char[] cbuf) : 从输入流中读取一些字符,并将它们存储到字符数组 中。
2.FileReader类的使用
(1)构造方法
FileReader(File file) : 创建一个新的 FileReader ,给定要读取的File对象。
FileReader(String fileName) : 创建一个新的 FileReader ,给定要读取的文件的名称。
(2)读取字符类型的两种方法
①读取字符: read()
②使用字符数组读取: read(char[] cbuf)
3.字符输出流
java.io.Writer 抽象类是表示用于写出字符流的所有类的超类,将指定的字符信息写出到目的地。
public abstract void close() :关闭此输出流并释放与此流相关联的任何系统资源。
public abstract void flush() :刷新此输出流并强制任何缓冲的输出字符被写出。
public void write(int c) :写出一个字符。
public void write(char[] cbuf) :将 b.length字符从指定的字符数组写出此输出流。
public abstract void write(char[] b, int off, int len) :从指定的字符数组写出 len字符,从偏移量off开始输出到此输出流。
public void write(String str) :写出一个字符串。
public write(String str, int off, int len) :写出一个字符串的一部分。
4.FileWriter类的使用
java.io.FileWriter 类是写出字符到文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区。
(1)构造方法
FileWriter(File file) : 创建一个新的 FileWriter,给定要读取的File对象。
FileWriter(String fileName) : 创建一个新的 FileWriter,给定要读取的文件的名称。
(2)写出数据的三组方法
①写出字符: write(int b)
②写出字符数组 : write(char[] cbuf) 和 write(char[] cbuf, int off, int len)
③写出字符串: write(String str) 和 write(String str, int off, int len)
(3)关闭和刷新
因为内置缓冲区的原因,如果不关闭输出流,无法写出字符到文件中。但是关闭的流对象,是无法继续写出数据的。如果我们既想写出数据,又想继续使用流,就需要flush 方法了。
flush() :刷新缓冲区,流对象可以继续使用。
close() :关闭流,释放系统资源。关闭前会刷新缓冲区。
5.字符输出流练习
从控制台循环接收用户录入的学生信息,输入格式为:学号-学生名字将学生信息保存到D盘下面的stu.txt文件中,一个学生信息占据一行数据。当用户输入end时停止输入。
try (FileWriter fw = new FileWriter("F:\\stu.txt");) {
Scanner sc = new Scanner(System.in);
System.out.println("输入end为退出程序...");
System.out.println("请输入学生学号和姓名(格式:学号-学生名字):");
String msg = sc.next();
while (!msg.equals("end")) {
fw.write(msg + "\r\n");
System.out.println("请继续输入或者退出:");
msg = sc.next();
}
} catch (IOException e) {
e.printStackTrace();
}
四、IO异常的处理
1.JDK7之前的标准异常处理
FileOutputStream fos=null;
try {
fos=new FileOutputStream("test.text");
fos.write("hello".getBytes());
}catch (IOException e) {
e.printStackTrace();
}finally {
if(fos!=null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.JDK7的新特性
该语句确保了每个资源在语句结束时关闭。所谓的资源(resource)是指在程序完成后,必须关闭的对象。
注意事项:
(1)try括号中的资源需实现AutoCloseable接口。
(2)try语句中声明的资源被隐式声明为final。
(3)如果要在try语句中管理多个资源,在每个资源之间使用分号分割即可。
格式:
try (创建流对象语句,如果多个,使用';'隔开) {
// 读写数据
} catch (IOException e) {
e.printStackTrace();
}
五、Properties类(********)
1.概述
java.util.Properties 继承于Hashtable ,来表示一个持久的属性集。它使用键值结构存储数据,每个键及其对应值都是一个字符串。
2.构造方法
public Properties() :创建一个空的属性列表。
3.基本保存数据的方法
public Object setProperty(String key, String value) : 保存一对属性。
public String getProperty(String key) :使用此属性列表中指定的键搜索属性值。
public Set<String> stringPropertyNames() :所有键的名称的集合。
4.持久化的方法
public void load(InputStream inStream) : 从字节输入流中读取键值对。
public void store(OutputStream outStream,String comments) :将Properties的数据保存到文件中。comments为注释,一般不写。
注意:持久化后的文件,必须使用.properties结尾。
5.键值对练习
我有一个文本文件score.txt,我知道数据是键值对形式的,但是不知道内容是什么。
请写一个程序判断是否有"lisi"这样的键存在,如果有就改变其实为"100"
score.txt文件内容如下:
zhangsan = 90
lisi = 80
wangwu = 85
//获取类路径下的score.txt文件
InputStream stream = Test08.class.getClassLoader().getResourceAsStream("score.txt");
//创建Properties类
Properties properties = new Properties();
//将stream类加载到类中
properties.load(stream);
//获取score.txt中的所有键
Set<String> strings = properties.stringPropertyNames();
//遍历键判断是否存在
for (String string : strings) {
if (string.equals("lisi")) {
properties.setProperty("lisi", "100");
}
}
//回写
properties.store(new FileWriter(new File("score.text")), null);