1、IO流概念:
一、基本概念
二、IO流分类
三、java.io流的四你们族
四、流的close和flush方法
五、java.id下经常使用的16个流html
2、FileInputStream字节输入流
一、FileInputStream完成字节流输入的流程
二、使用while优化FileInputStream读取流程
三、FileInputStream最终版,使用byte数组读取
四、FileInputStream的available
五、FileInputStream的skip方法java
3、FileOutputStream字节输出流
一、FileOutputStream概念
二、FileOutputStream输出流程
三、改进FileInputStream+String输出
四、文件复制(FileInputStream+FileOutputStream)数组
4、FileReader与FileWrite
一、FileReader概念
二、举例FileReader
三、FileWrite概念:
四、举例FileWrite:
五、复制普通文件(FileReader与FileWrite):工具
5、带有缓冲区的字符流
一、BufferedReader概念:
二、举例说明BufferedReader:
三、节点流与包装流
四、BufferedWrite:带有缓冲区的字符输出流 测试
6、数据流
一、DataOutputStream概念
二、举例说明:DataOutputStream
三、DataInputStream流概念:
四、举例说明:DataInputStream优化
7、标准输出流
一、PrintStream标准字节输出流:
二、更改标准输出流的输出方向
三、日志工具生成原理:spa
8、File类
https://www.cnblogs.com/mrwhite2020/p/14322392.html3d
9、对象流
https://www.cnblogs.com/mrwhite2020/p/14322446.html日志
10、IO和Properties
https://www.cnblogs.com/mrwhite2020/p/14322463.htmlcode
------------------------------------------分割线,如下为正文-------------------------------------------------
I:Input
O:Output
经过IO能够完成硬盘文件的读和写。
(1)按照流的方向分类:
输入流(Input)或者称为读(Reader)
输出流(Output)或者称为写(Write)
(2)按照读取数据方式不一样分类:
字节流:按照字节方式读取数据,一次读取1个字节byte,等同一个8个二进制位,这种流是万能的,什么类型的文件均可以读取,包括:文本文件、图片、视频、声音等
字符流:按照字符方式读取数据,一次读取一个字符,这种流是为了方便读取普通文件而存在,这种流不能读取图片、声音、视频、word等,只能读取纯文本文件。
假设文件test.txt 内容为:"h世界"
字节流读取:第一次读'h'(占用一个字节),第二次读'世'字符的一半(占用一个字节)
字符流读取:第一次读'h'(占用一个字节),第二次读'世'字符(占用一个字符)
(1)java.io.InputStream字节输入流
(2)java.io.OutputStream字节输出流
(3)java.io.Reader字符输入流
(4)java.io.Writer字符输出流
在java中以Stream结尾都是字节流,以Reader/Writer结尾都是字符流
(1)close()
全部的流都实现java.io.closeble接口,都是能够关闭的,都右close方法。
流是一个管理,是内存与硬盘之间的通道,用完以后必定要关闭,否则会耗费不少资源,养成好习惯,用完流必定要关闭。
(2)flush()
全部的输出流都实现了java.io.Flushable接口,均可以刷新,都包含flush方法。
养成好习惯,输出流输出玩都须要flush刷新一下,表示将通道/管道当中的剩余未输出的数据强行输出完,即清空管道,没有使用flush方法会致使数据丢失
(1)文件专属:
java.io.FileInputStream;
java.io.FileOutputStream;
java.io.FileReader;
java.io.FileWriter;
(2)转换流:字节流转为字符流
java.io.InputStream;
java.io.OutputStream;
(3)缓冲区专属:
java.io.BufferedInputStream;
java.io.BufferedOutputStream;
java.io.BufferedReader;
java.io.BufferedWriter;
(4)数据专属:
java.io.DataInputStream;
java.io.DataOutputStream;
(5)标准输出流:
java.io.PrintStream;
java.io.PrintWriter;
(6)对象专属:
java.io.ObjectInputStream;
java.io.ObjectOutputStream;
(1)准备文件以下:
(2)建立字节流输入对象,Idea自动将路径变斜杠
(3)alt+回车添加try+catch或者上报异常,这里选择try+catch
(4)第二种文件路径编写方式"\"与"//"等价
(5)增长finally语句且初始化流放在try+catch语句外,并添加流的关闭,流关闭前须要增长流的判空ifn可默认生成 if(fis==null)
(6)增长流的读取,并添加try+catch使用alt+回车,这里建议选择第一种异常
第一种:增长catch使用细粒度的异常
第二种:方法声明异常
第三种:替换外层FIleNotFount为IO异常
第四种:内层在增长try+catch
(7)查看打印结果为a对应的字符ascII码值97
(8)可重复读取6次,最后一次读取不到返回-1
二、使用while优化FileInputStream读取流程
三、FileInputStream最终版,使用byte数组读取
(1)查看剩余的字节数
(2)available的做用:能够不适用while循环,直接一次读取所有的字节,可是不适合大的文件,由于byte数组不能太大
字节输出流,从内存到硬盘
(1)使用byte数组+write方法+flush方法写入
(2)检查文件结果,相对路径为项目根目录下:
(3)再次执行,会将原文件中内容覆盖,依然输出:abcdab
(4)修改构造方法,true表明文本的追加
(5)查看相对路径下的文本执行结果:文本追加了内容
(1)使用String转byte数组输出
(2)查看输出结果,追加一段String字符串
四、文件复制(FileInputStream+FileOutputStream)
(1)流程:拷贝过程是一边读、一边写;文件类型任意,是万能的
(2)举例文件复制:
1 package JAVAADVANCE; 2
3 import java.io.FileInputStream; 4 import java.io.FileNotFoundException; 5 import java.io.FileOutputStream; 6 import java.io.IOException; 7
8 public class TestAdvance33IOTest08 { 9 public static void main(String[] args) { 10 FileInputStream fis=null; 11 FileOutputStream fos=null; 12 try { 13 //建立一个输入对象流
14 fis=new FileInputStream("D:\\javaTest\\inFile\\甜蜜家园第01集.mp4"); 15 //建立一个输出对象流
16 fos=new FileOutputStream("D:\\javaTest\\outFile\\甜蜜家园第01集.mp4"); 17 //准备一个byte数组,1024byte=1KB,*1024=1M,一次最多读1M
18 byte[] bytes=new byte[1024*1024]; 19 int readCount=0; 20 while ((readCount=fis.read(bytes))!=-1) 21 { 22 //读取多少,写多少
23 fos.write(bytes,0,readCount); 24 } 25 fos.flush(); 26 } catch (FileNotFoundException e) { 27 e.printStackTrace(); 28 } catch (IOException e) { 29 e.printStackTrace(); 30 } finally { 31 //fos与fis的关闭分开try catch比较好,避免互相影响,有流没有关闭
32 if (fos != null) { 33 try { 34 fos.close(); 35 } catch (IOException e) { 36 e.printStackTrace(); 37 } 38 } 39 if(fis!=null){ 40 try { 41 fis.close(); 42 } catch (IOException e) { 43 e.printStackTrace(); 44 } 45 } 46 } 47
48
49
50
51 } 52 }
查看文件输出结果
\
文件字符输入流,只能读取普通文本,读取文本内容时比较方便、快捷
1 package JAVAADVANCE; 2 import java.io.*; 3 public class TestAdvance33IOTest09FileReader { 4 public static void main(String[] args) { 5 FileReader reader= null; 6 try { 7 //建立字符输入流
8 reader=new FileReader("C:\\Users\\Mr.White\\IdeaProjects\\javaAdvance\\myTestFile01"); 9 //开始读,使用char数组,一次读取4个字符
10 char[] chars=new char[4]; 11 int readCount=0; 12 while ((readCount=reader.read(chars))!=-1){ 13 System.out.println(new String(chars,0,readCount)); 14 } 15 } catch (FileNotFoundException e) { 16 e.printStackTrace(); 17 } catch (IOException e) { 18 e.printStackTrace(); 19 } finally { 20 if (reader != null) { 21 try { 22 reader.close(); 23 } catch (IOException e) { 24 e.printStackTrace(); 25 } 26 } 27 } 28 } 29 }
检查源文件与读取的内容
文件字符输出流,只能输出普通文本
1 package JAVAADVANCE; 2 import java.io.FileWriter; 3 import java.io.IOException; 4 public class TestAdvance33IOTest10FileWrite { 5 public static void main(String[] args) { 6 FileWriter out = null; 7 try { 8 //建立字符输出流对象,true使用追加写入模式,不然从新执行会覆盖
9 out=new FileWriter("fileWriteTest01",true); 10 //开始写,使用char数组
11 char[] chars={'我','是','中','国','人'}; 12 //写入所有char数组
13 out.write(chars); 14 //再写入部分char数组,第3个字符开始,3个字符
15 out.write(chars,2,3); 16 //直接写入String
17 out.write("我是个JAVA工程师"); 18 out.flush(); 19 } catch (IOException e) { 20 e.printStackTrace(); 21 }finally { 22 if (out != null) { 23 try { 24 out.close(); 25 } catch (IOException e) { 26 e.printStackTrace(); 27 } 28 } 29 } 30 } 31 }
查看输出结果,相对路径为工程根目录下
五、复制普通文件(FileReader与FileWrite):
(1)使用FileReader与FileWrite进行拷贝,只能拷贝普通文本文件
(2)举例复制普通文件:
1 package JAVAADVANCE; 2 import java.io.FileNotFoundException; 3 import java.io.FileReader; 4 import java.io.FileWriter; 5 import java.io.IOException; 6 public class TestAdvance33IOTest11NormalFileCopy { 7 public static void main(String[] args) { 8 FileReader in =null; 9 FileWriter out = null; 10 try { 11 //建立字符输入流
12 in=new FileReader("D:\\javaTest\\inFile\\fileWriteTest01"); 13 //建立字符输出流
14 out=new FileWriter("D:\\javaTest\\outFile\\fileWriteTest01"); 15 //一边读一边写
16 char[] chars=new char[1024*512]; //一次读取1M文件
17 int readCount=0; 18 while ((readCount=in.read(chars))!=-1){ 19 out.write(new String(chars,0,readCount)); 20 } 21 //写完后刷新
22 out.flush(); 23 } catch (FileNotFoundException e) { 24 e.printStackTrace(); 25 } catch (IOException e) { 26 e.printStackTrace(); 27 } finally { 28 if (in != null) { 29 try { 30 in.close(); 31 } catch (IOException e) { 32 e.printStackTrace(); 33 } 34 } 35 if (out != null) { 36 try { 37 out.close(); 38 } catch (IOException e) { 39 e.printStackTrace(); 40 } 41 } 42 } 43 } 44 }
查看复制后结果
带有缓冲区的字符输入流,使用此流不须要自定义char数组,或者说不须要自定义byte数组,自带缓冲区。
(1)准备文件
(2)按照行读取文件
package JAVAADVANCE; import java.io.*; public class TestAdvance33IOTest12BufferedReader { //异常先抛出
public static void main(String[] args) throws IOException { FileReader reader=new FileReader("D:\\javaTest\\inFile\\fileWriteTest02"); //FileReader为节点流,BufferedReader为包装流/处理流
BufferedReader br=new BufferedReader(reader); //读第一行
String firstLine = br.readLine(); System.out.println(firstLine); //读第二行
String secondLine = br.readLine(); System.out.println(secondLine); //读第三行
String thirdLine = br.readLine(); System.out.println(thirdLine); //只须要关闭最外层的流,对于包装流来讲
br.close(); } }
(3)循环读取所有文件
1 package JAVAADVANCE; 2 import java.io.BufferedReader; 3 import java.io.FileReader; 4 import java.io.IOException; 5 public class TestAdvance33IOTest12BufferedReader02 { 6 //异常先抛出
7 public static void main(String[] args) throws IOException { 8 FileReader reader=new FileReader("D:\\javaTest\\inFile\\fileWriteTest02"); 9 //FileReader为节点流,BufferedReader为包装流/处理流
10 BufferedReader br=new BufferedReader(reader); 11 //使用String字符串读取
12 String s=null; 13 while ((s=br.readLine())!=null){ 14 System.out.println(s); 15 } 16 //只须要关闭最外层的流,对于包装流来讲
17 br.close(); 18 } 19 }
检查执行结果
(4)print方法测试readLine方法不带换行符
1 package JAVAADVANCE; 2 import java.io.BufferedReader; 3 import java.io.FileReader; 4 import java.io.IOException; 5 public class TestAdvance33IOTest12BufferedReader02 { 6 //异常先抛出
7 public static void main(String[] args) throws IOException { 8 FileReader reader=new FileReader("D:\\javaTest\\inFile\\fileWriteTest02"); 9 //FileReader为节点流,BufferedReader为包装流/处理流
10 BufferedReader br=new BufferedReader(reader); 11 //使用String字符串读取
12 String s=null; 13 while ((s=br.readLine())!=null){ 14 //print方法测试readLine方法不带换行符
15 System.out.print(s); 16 } 17 //只须要关闭最外层的流,对于包装流来讲
18 br.close(); 19 } 20 }
查看执行结果
(1)节点流与包装流都是相对而言
(2)举例说明:节点流与包装流
如下例子:
in与reader:in为节点流,reader为包装流
reader与br:reader与节点流,br为包装流
package JAVAADVANCE; import java.io.*; public class TestAdvance33IOTest12BufferedReader03 { //异常先抛出
public static void main(String[] args) throws IOException { FileInputStream in=new FileInputStream("D:\\javaTest\\inFile\\fileWriteTest02"); //经过InputStreamReader转换流将字节流转换为字符流
InputStreamReader reader=new InputStreamReader(in); BufferedReader br =new BufferedReader(reader); //使用String字符串读取
String line=null; while ((line=br.readLine())!=null){ //print方法测试readLine方法不带换行符
System.out.println(line); } //只须要关闭最外层的流,对于包装流来讲
br.close(); } }
查看运行结果:
(1)举例说明BufferedWrite
package JAVAADVANCE; import java.io.*; public class TestAdvance33IOTest13BufferedWrite { //异常先抛出
public static void main(String[] args) throws IOException { BufferedWriter out=new BufferedWriter(new FileWriter("D:\\javaTest\\outFile\\fileWriteTest02")); out.write("hello world"); out.write("\nhello kitty"); out.flush(); out.close(); } }
查看执行结果
(2)使用包装流追加输出
package JAVAADVANCE; import java.io.*; public class TestAdvance33IOTest13BufferedWrite02 { //异常先抛出
public static void main(String[] args) throws IOException { BufferedWriter out=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("D:\\javaTest\\outFile\\fileWriteTest02",true))); out.write("\n这是继续使用包装流追加的文字"); out.flush(); out.close(); } }
查看执行结果:
数据专属的流
这个流能够将数据连同数据的类型一并写入文件
注意:这个文件不一样普通文本文档(这个文件使用记事本打不开)
package JAVAADVANCE; import java.io.*; public class TestAdvance33IOTest14DataOutputStream01 { //异常先抛出
public static void main(String[] args) throws IOException { //建立数据专属字节输出流
DataOutputStream dos=new DataOutputStream(new FileOutputStream("D:\\javaTest\\outFile\\fileWriteTest03")); byte b=100; short s=200; int i=300; float t=400F; double d=3.14; boolean sex=false; char c='a'; dos.writeByte(b); dos.writeShort(s); dos.writeInt(i); dos.writeFloat(t); dos.writeDouble(d); dos.writeBoolean(sex); dos.writeChar(c); dos.flush(); dos.close(); } }
查看文件结果:没法使用记事本或notepad++打开,须要使用DataInputStream流打开,而且读的顺序须要与写的顺序一致。
数据字节输入流,DataOutputStream流写的文件只能使用DataInputStream打开,而且读的顺序须要和写的顺序一致。
1 package JAVAADVANCE; 2 import java.io.*; 3 public class TestAdvance33IOTest15DataInputStream01 { 4 //异常先抛出
5 public static void main(String[] args) throws IOException { 6 //建立数据专属字节输入流
7 DataInputStream dis =new DataInputStream(new FileInputStream("D:\\javaTest\\outFile\\fileWriteTest03")); 8 //开始读,读的顺序要与写的时候保持一致。
9 byte b= dis.readByte(); 10 short s=dis.readShort(); 11 int i=dis.readInt(); 12 float t =dis.readFloat(); 13 double d=dis.readDouble(); 14 boolean sex=dis.readBoolean(); 15 char c=dis.readChar(); 16 dis.close(); 17 System.out.println(b); 18 System.out.println(s); 19 System.out.println(i); 20 System.out.println(t); 21 System.out.println(d); 22 System.out.println(sex); 23 System.out.println(c); 24
25 } 26 }
查看显示结果
标准字节输出流,默认输出到控制台。
1 package JAVAADVANCE; 2 import java.io.IOException; 3 import java.io.PrintStream; 4 public class TestAdvance33IOTest16PrintStream01 { 5 //异常先抛出
6 public static void main(String[] args) throws IOException { 7 //标准输出流直接输出到控制台
8 System.out.println("hello world"); 9 //换一种写法
10 PrintStream ps=System.out; 11 ps.println("hello zhangsan"); 12 ps.println("hello lisi"); 13 //标准输出流不须要手动关闭
14 } 15 }
1 package JAVAADVANCE; 2 import java.io.FileOutputStream; 3 import java.io.IOException; 4 import java.io.PrintStream; 5 public class TestAdvance33IOTest16PrintStream01 { 6 //异常先抛出
7 public static void main(String[] args) throws IOException { 8 //更改标准输出流的输出方向,指向log文件
9 System.setOut(new PrintStream(new FileOutputStream("log"))); 10 //再次输出
11 System.out.println("hello world"); 12 System.out.println("hello kitty"); 13 } 14 }
查看项目根目录的输出文件
package JAVAADVANCE; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.PrintStream; import java.text.SimpleDateFormat; import java.util.Date; public class TestAdvance33IOTest16LogTest { //异常先抛出
public static void log(String msg) { try { PrintStream out=new PrintStream(new FileOutputStream("log.txt",true)); //改变文件的输出方向
System.setOut(out); //当前日期格式
Date nowTime = new Date(); SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS"); String strTime=sdf.format(nowTime); } catch (FileNotFoundException e) { e.printStackTrace(); } } }
编写测试程序开始测试日志打印
1 package JAVAADVANCE; 2 public class TestAdvance33IOTest16LogTest { 3 public static void main(String[] args) { 4 //测试工具是否好用
5 TestAdvance33IOTest16PrintStream02.log("调用了Sytem的gc()方法,建议启动垃圾回收"); 6 TestAdvance33IOTest16PrintStream02.log("调用了userService的dosome()方法"); 7 TestAdvance33IOTest16PrintStream02.log("用户正在尝试登陆,验证失败"); 8 } 9 }
查看输出结果
File类参照以下章节:
https://www.cnblogs.com/mrwhite2020/p/14322392.html
对象流、序列化与反序列化参考以下章节:
https://www.cnblogs.com/mrwhite2020/p/14322446.html
IO和Properties联合使用参考以下章节: