同步与异步:描述的是进程间的消息通知机制
-
同步:当前任务必须等待上一个任务执行完成,
-
异步:当前任务无需等待上一个任务完成,就可以执行下一个任务,
阻塞和非阻塞:描述线程在等待时的行为
-
阻塞:在等待时,当前线程会进入阻塞状态,等待其他任务完成之后被唤醒
-
非阻塞:在等待其他资源时,会一直轮询等待,不会进入休眠状态
1.javaIO流的分类
-
按照流的流向分,可以分为输入流和输出流;
-
按照操作单元划分,可以划分为字节流和字符流;
-
按照流的角色划分为节点流和处理流。
Java Io流共涉及40多个类,这些类看上去很杂乱,但实际上很有规则,而且彼此之间存在非常紧密的联系, Java I0流的40多个类都是从如下4个抽象类基类中派生出来的。
- InputStream/Reader: 所有的输入流的基类,前者是字节输入流,后者是字符输入流。
- OutputStream/Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流。
2.IO
能够说出IO流的分类和功能
能够使用字节输出流写出数据到文件
能够使用字节输入流读取数据到程序
能够理解读取数据read(byte[])方法的原理
能够使用字节流完成文件的复制
能够使用FileWirter写数据到文件
能够说出FileWriter中关闭和刷新方法的区别
能够使用FileWriter写数据的5个方法
能够使用FileWriter写数据实现换行和追加写
能够使用FileReader读数据
能够使用FileReader读数据一次一个字符数组
能够使用Properties的load方法加载文件中配置信息
IO模型:会先将字符读入linux缓冲区域,再读入用户线程的区域
1. I/O的分类
根据数据流向:输入流,输出流
根据数据类型:字节流,字符流
| 输入流 | 输出流 | |
|---|---|---|
| 字节流 | 字节输入流 InputStream | 字节输出流 OutputStream |
| 字符流 | 字符输入流 Reader | 字符输出流 Writer |
3. 字节流OutputStream/InputStream
(一)共性方法
- public void close() :关闭此输出流并释放与此流相关联的任何系统资源。
- public void flush() :刷新此输出流并强制任何缓冲的输出字节被写出。
- public void write(byte[] b) :将 b.length字节从指定的字节数组写入此输出流。
- public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。
- public abstract void write(int b) :将指定的字节输出流。
(二) FileOutputStream类
OutputStream子类FileOutputStream文件输出流,用于将数据写出到文件
-
构造方法
public FileOutputStream(File file) :创建文件输出流以写入由指定的 File对象表示的文件。
public FileOutputStream(String name) : 创建文件输出流以指定的名称写入文件。
public class FileOutputStreamConstructor throws IOException { public static void main(String[] args) { // 使用File对象创建流对象 File file = new File("a.txt"); FileOutputStream fos = new FileOutputStream(file); // 使用文件名称创建流对象 FileOutputStream fos = new FileOutputStream("b.txt"); } } -
写出字节流
write(int b) 方法,每次可以写出一个字节数据 。
File file = new File("C:\\Users\\YT\\Documents\\2020\\01java基础语法\\code\\aa\\1.txt"); FileOutputStream fos = new FileOutputStream(file); fos.write(97); fos.close(); 输出结果:awrite(byte[] b) ,每次可以写出数组中的数据 。
File file1 = new File("C:\\Users\\YT\\Documents\\2020\\01java基础语法\\code\\aa\\2.txt"); FileOutputStream fos1 = new FileOutputStream(file1); byte[] b="好好学啊".getBytes(); fos1.write(b); fos1.close(); 输出结果:好好学啊write(byte[] b, int off, int len) ,每次写出从off索引开始,len个字节 。
// 使用文件名称创建流对象 FileOutputStream fos = new FileOutputStream("fos.txt"); // 字符串转换为字节数组 byte[] b = "abcde".getBytes(); // 写出从索引2开始,2个字节。索引2是c,两个字节,也就是cd。 fos.write(b,2,2); // 关闭资源 fos.close(); 输出结果:cd -
数据追加续写
public FileOutputStream(File file, boolean append) : 创建文件输出流以写入由指定的 File对象表示的文件。
public FileOutputStream(String name, boolean append) : 创建文件输出流以指定的名称写入文件。 这两个构造方法,参数中都需要传入一个boolean类型的值, true 表示追加数据, false 表示清空原有数据。
File file1 = new File("C:\\Users\\YT\\Documents\\2020\\01java基础语法\\code\\aa\\2.txt"); FileOutputStream fos1 = new FileOutputStream(file1,true); byte[] b1="好好学啊".getBytes(); fos1.write(b1); File file2 = new File("C:\\Users\\YT\\Documents\\2020\\01java基础语法\\code\\aa\\2.txt"); FileOutputStream fos2 = new FileOutputStream(file2,true); byte[] b2="天天向上".getBytes(); fos1.write(b2); fos1.close(); fos2.close(); -
写出换行
Windows系统里,每行结尾是 回车+换行 ,即 \r\n ;
Unix系统里,每行结尾只有 换行 ,即 \n ;
Mac系统里,每行结尾是 回车 ,即 \r 。从 Mac OS X开始与Linux统一。
public class FOSWrite { public static void main(String[] args) throws IOException { // 使用文件名称创建流对象 FileOutputStream fos = new FileOutputStream("fos.txt"); // 定义字节数组 byte[] words = {97,98,99,100,101}; // 遍历数组 for (int i = 0; i < words.length; i++) { // 写出一个字节 fos.write(words[i]); // 写出一个换行, 换行符号转成数组写出 fos.write("\r\n".getBytes()); } // 关闭资源 fos.close(); } }
(三)FileInputStream类
-
构造方法
FileInputStream(File file) : 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。
FileInputStream(String name) : 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。
File file = new File("C:\\Users\\YT\\Documents\\2020\\01java基础语法\\code\\aa\\1.txt"); FileInputStream fis1=new FileInputStream(file); FileInputStream fis2=new FileInputStream("C:\\Users\\YT\\Documents\\2020\\01java基础语法\\code\\aa\\1.txt"); -
读取字节数据
read() 方法读取字节,每次可以读取一个字节的数据,提升为int类型,读取到文件末尾,返回 -1
public class 输入字节流 { public static void main(String[] args) throws IOException { File file = new File("C:\\Users\\YT\\Documents\\2020\\01java基础语法\\code\\aa\\1.txt"); FileInputStream fis1=new FileInputStream(file); int b=0; while((b=fis1.read())!=-1){ System.out.println((char)b); } System.out.println(b); fis1.close(); } }read(byte[] b) ,每次读取b的长度个字节到数组中,返回读取到的有效字节个数,读取到末尾时,返回 -1
public class 输入字节流 { public static void main(String[] args) throws IOException { File file = new File("C:\\Users\\YT\\Documents\\2020\\01java基础语法\\code\\aa\\1.txt"); FileInputStream fis1=new FileInputStream(file); byte[] b=new byte[2]; int len=0; while((len =fis1.read(b))!=-1){ System.out.println(len); System.out.println(new String(b,0,len)); } fis1.close(); } }
(四)案例复制图片
复制一张图片到目的地址
public class 输入字节流 {
public static void main(String[] args) throws IOException {
File fileInput = new File("C:\\Users\\YT\\Documents\\2020\\01java基础语法\\code\\aa\\img.jpg");
FileInputStream fis=new FileInputStream(fileInput);
FileOutputStream fos = new FileOutputStream("C:\\Users\\YT\\Documents\\2020\\01java基础语法\\code\\aa\\bb\\img_result.jpg");
byte[] b=new byte[1024];
int len=0;
while((len=fis.read(b))!=-1){
fos.write(b,0,len);
}
fos.close();
fis.close();
}
}
3.字符流Reader/Write
(一)字符输入流Reader
以字符为单位读写数据,专门用于处理文本文件
-
共同方法
public void close() :关闭此流并释放与此流相关联的任何系统资源。
public int read() : 从输入流读取一个字符。
public int read(char[] cbuf) : 从输入流中读取一些字符,并将它们存储到字符数组 cbuf中 。
(二)FileReader类
-
构造方法
FileReader(File file) : 创建一个新的 FileReader ,给定要读取的File对象。
FileReader(String fileName) : 创建一个新的 FileReader ,给定要读取的文件的名称。
public class FileReaderConstructor throws IOException{ public static void main(String[] args) { // 使用File对象创建流对象 File file = new File("a.txt"); FileReader fr = new FileReader(file); // 使用文件名称创建流对象 FileReader fr = new FileReader("b.txt"); } } -
读取字符数据
read 方法,每次可以读取一个字符的数据,提升为int类型,读取到文件末尾,返回 -1
public class 输入字符流 { public static void main(String[] args) throws IOException { File file = new File("C:\\Users\\YT\\Documents\\2020\\01java基础语法\\code\\aa\\1.txt"); FileReader fir = new FileReader(file); int b=0; while((b=fir.read())!=-1){ System.out.println((char)b); } fir.close(); } }read(char[] cbuf) ,每次读取b的长度个字符到数组中,返回读取到的有效字符个数,读取到末尾时,返回 -1
public class 输入字符流 { public static void main(String[] args) throws IOException { File file = new File("C:\\Users\\YT\\Documents\\2020\\01java基础语法\\code\\aa\\1.txt"); FileReader fir = new FileReader(file); char[] buf=new char[2]; int b=0; while((b=fir.read(buf))!=-1){ System.out.println(new String(buf,0,b)); } fir.close(); } }
(三) 字符输出流FileWrite
-
共同方法
void write(int c) 写入单个字符。
void write(char[] cbuf) 写入字符数组。
abstract void write(char[] cbuf, int off, int len) 写入字符数组的某一部分,off数组的开始索引,len写的字符个数。
void write(String str) 写入字符串。
void write(String str, int off, int len) 写入字符串的某一部分,off字符串的开始索引,len写的字符个数。
void flush() 刷新该流的缓冲。
void close() 关闭此流,但要先刷新它。
(四) FlieWriter类
-
构造方法
FileWriter(File file) : 创建一个新的 FileWriter,给定要读取的File对象。
FileWriter(String fileName) : 创建一个新的 FileWriter,给定要读取的文件的名称。
public class FileWriterConstructor { public static void main(String[] args) throws IOException { // 使用File对象创建流对象 File file = new File("a.txt"); FileWriter fw = new FileWriter(file); // 使用文件名称创建流对象 FileWriter fw = new FileWriter("b.txt"); } } -
写出字符数据
write(int b) 方法,每次可以写出一个字符数据
public class 输出字符流 { public static void main(String[] args) throws IOException { FileWriter fiw = new FileWriter("C:\\Users\\YT\\Documents\\2020\\01java基础语法\\code\\aa\\2.txt"); fiw.write(97); fiw.write("a"); fiw.write("你好啊"); fiw.write(3000); fiw.close(); } }write(char[] cbuf)
write(char[] cbuf, int off, int len) ,每次可以写出字符数组中的数据,用法类似FileOutputStream
public class 输出字符流 { public static void main(String[] args) throws IOException { FileWriter fiw = new FileWriter("C:\\Users\\YT\\Documents\\2020\\01java基础语法\\code\\aa\\2.txt"); char[] chars="测试写入功能,看看是否可用".toCharArray(); fiw.write(chars); fiw.write("\n"); fiw.write(chars,0,chars.length); fiw.close(); } } -
写出字符串
write(String str) 和 write(String str, int off, int len) ,每次可以写出字符串中的数据,更为方便,
public class FWWrite { public static void main(String[] args) throws IOException { // 使用文件名称创建流对象 FileWriter fw = new FileWriter("fw.txt"); // 字符串 String msg = "黑马程序员"; // 写出字符数组 fw.write(msg); //黑马程序员 // 写出从索引2开始,2个字节。索引2是'程',两个字节,也就是'程序'。 fw.write(msg,2,2); // 程序 // 关闭资源 fos.close(); } } -
刷新与关闭
flush :刷新缓冲区,流对象可以继续使用。 close :先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了。
public class FWWrite { public static void main(String[] args) throws IOException { // 使用文件名称创建流对象 FileWriter fw = new FileWriter("fw.txt"); // 写出数据,通过flush fw.write('刷'); // 写出第1个字符 fw.flush(); fw.write('新'); // 继续写出第2个字符,写出成功 fw.flush(); // 写出数据,通过close fw.write('关'); // 写出第1个字符 fw.close(); fw.write('闭'); // 继续写出第2个字符,【报错】java.io.IOException: Stream closed fw.close(); } }4.缓冲流NIO
-
字节缓冲流: BufferedInputStream , BufferedOutputStream
-
字符缓冲流: BufferedReader , BufferedWriter
缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高读写的效率。
(一) 字节缓冲流
-
构造方法
public BufferedInputStream(InputStream in) :创建一个 新的缓冲输入流。
public BufferedOutputStream(OutputStream out) : 创建一个新的缓冲输出流。
// 创建字节缓冲输入流 BufferedInputStream bis = new BufferedInputStream(new FileInputStream("bis.txt")); // 创建字节缓冲输出流 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("bos.txt")); -
代码演示
import java.io.*; public class 缓冲字节流 { public static void main(String[] args) throws IOException { BufferedInputStream bis = new BufferedInputStream(new FileInputStream("C:\\Users\\YT\\Documents\\2020\\01java基础语法\\code\\aa\\img.jpg")); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("C:\\Users\\YT\\Documents\\2020\\01java基础语法\\code\\aa\\bb\\img2.jpg")); int len=0; byte[] b=new byte[8*1024]; while((len=bis.read(b))!=-1){ bos.write(b,0,len); } bos.close(); bis.close(); } }
(二) 字符缓冲流
-
构造方法 BufferedReader/BufferedWriter
public BufferedReader(Reader in) :创建一个 新的缓冲输入流。
public BufferedWriter(Writer out) : 创建一个新的缓冲输出流。
-
特有方法
BufferedReader: public String readLine() : 读一行文字。
BufferedWriter: public void newLine() : 写一行行分隔符,由系统属性定义符号。
public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new FileReader("C:\\Users\\YT\\Documents\\2020\\01java基础语法\\code\\aa\\2.txt")); String line=null; while((line=br.readLine())!=null){ System.out.println(line); System.out.println("----------------------"); } br.close(); } public static void main(String[] args) throws IOException { BufferedWriter bw = new BufferedWriter(new FileWriter("C:\\Users\\YT\\Documents\\2020\\01java基础语法\\code\\aa\\1.txt")); bw.write("12345667",2,2); bw.newLine(); bw.write("12345667",4,2); bw.newLine(); bw.write("12345667",6,2); bw.close(); }