目录
Java I/O流
一、什么是流?
二、流的分类
三、字节流
1.文件字节流
2.字节流复制文件
3.字节缓冲流
4.对象流
四、字符流
1.文件字符流
2.字符流复制文件
3.字符缓冲流
五、打印流
六、转换流
InputStreamReader
OutputStreamWriter
七、File类
1.分隔符
2.文件操作
3.文件夹操作
4.FileFilter接口
5.递归遍历和递归删除
补充:Properties
概念:内存与存储设备之间传输数据的通道。
按方向
输入流:将<存储设备>中的内容读入到<内存>中。
输出流:将<内存>中的内容写入到<存储设备>中。
文件—>程序(输入流);程序—>文件(输出流)
按单位
字节流:以字节为单位,可以读写所有数据。
字符流:以字符为单位,只能读写文本数据。
按功能
节点流:具有实际传输数据的读写功能。
过滤流:在节点流的基础之上增强功能。
字节流的父类(抽象类):
InputStream:字节输入流
public int read(){}
public int read(byte[] b){}
Public int read(byte[] b,int off,int len){}
OutputStream:字节输出流
public void write(int n){}
public void write(byte[] b){}
public void write(byte[] b,int off,int len){}
FileInputStream:
public int read(byte[] b)
从流中读取多个字节,将读到内容存入b数组,返回实际读到的字节数;如果达到文件的尾部,则返回-1.
package rcl; import java.io.FileInputStream; public class Demo01 { public static void main(String[] args) throws Exception { //1.创建文件输入流,并指定路径 FileInputStream fis=new FileInputStream("/Users/tomyoung/IdeaProjects/aaa.txt"); //2.读取文件 //单个字节读取 //fis.read();//只能读一个字节 int data=0; while((data=fis.read())!=-1){ System.out.print((char)data); } fis.close(); System.out.println(); System.out.println("执行完毕"); //多个字节读取 FileInputStream fis2=new FileInputStream("/Users/tomyoung/IdeaProjects/aaa.txt"); byte[] buf=new byte[3]; int gs=0; while((gs=fis2.read(buf))!=-1){ System.out.println(new String(buf,0,gs)); } fis2.close(); } } /* 输出结果: abcdefg 执行完毕 abc def g */
FileOutputStream:
public void write(byte[] b)
一次写多个字节,将b数组中所有字节,写入输出流。
package rcl; import java.io.FileOutputStream; public class Demo02 { public static void main(String[] args) throws Exception { //1.创建文件字节输出流对象 FileOutputStream fos=new FileOutputStream("/Users/tomyoung/IdeaProjects/bbb.txt"); FileOutputStream fos2=new FileOutputStream("/Users/tomyoung/IdeaProjects/ccc.txt"); //2.写入文件 fos.write(97); fos.write('b'); fos.write('c'); fos.close(); System.out.println("执行完毕"); String str="hello wangxi"; fos2.write(str.getBytes()); } }
package rcl; import java.io.FileInputStream; import java.io.FileOutputStream; public class Demo03 { public static void main(String[] args) throws Exception { //1.创建文件输入流 FileInputStream fis= new FileInputStream("/Users/tomyoung/IdeaProjects/aaa.txt"); //2.文件字节输出流 FileOutputStream fos=new FileOutputStream("/Users/tomyoung/IdeaProjects/ddd.txt"); //实现复制,一边读取一边写 byte[] buf=new byte[1034]; int count=0; while((count=fis.read(buf))!=-1){ fos.write(buf,0,count); } fis.close(); fos.close(); } }
缓冲流:BufferedInputStream/BufferOutputStream
提高IO效率,减少访问磁盘的次数。
数据存储在缓冲区冲,flush是将缓冲区的内容写入文件中,也可以直接close。
BufferedInputStream
package rcl; import java.io.BufferedInputStream; import java.io.FileInputStream; public class Demo04 { public static void main(String[] args) throws Exception { //1.创建一个BufferedInputStream FileInputStream fis=new FileInputStream("/Users/tomyoung/IdeaProjects/aaa.txt"); BufferedInputStream bis=new BufferedInputStream(fis); //2.读取 int data=0; while((data=bis.read())!=-1){ System.out.print((char)data); } //3.关闭 bis.close(); } }
BufferOutputStream
package rcl; import java.io.BufferedOutputStream; import java.io.FileOutputStream; public class Demo05 { public static void main(String[] args) throws Exception { //1.创建输出流 FileOutputStream fos=new FileOutputStream("/Users/tomyoung/IdeaProjects/eee.txt"); BufferedOutputStream bos= new BufferedOutputStream(fos); //2.写入文件 for(int i=0;i<10;i++){ bos.write("helloWorld".getBytes());//写入缓冲区 bos.flush();//刷新到硬盘 } //3.关闭(内部调用flush方法) bos.close(); } }
对象流:ObjectOutputStream/ObjectInputStream
增强了缓冲区功能
增强了读写8种基本数据和字符串功能
增强了读写对象的功能:
readObject()从六种读取一个对象
writeObject(Object obj)向流中写入一个对象
//学生类 package rcl; import java.io.Serializable; public class Student implements Serializable { private String name; private int age; public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
ObjectOutputStream序列化
package rcl; import java.io.FileOutputStream; import java.io.ObjectOutputStream; public class Demo06 { public static void main(String[] args) throws Exception { //1.创建对象流 FileOutputStream out=new FileOutputStream("/Users/tomyoung/IdeaProjects/stu.bin"); ObjectOutputStream oos=new ObjectOutputStream(out); //2。序列化(写入操作) Student zhangsan=new Student("lilMood",20);//序列化的类必须实现Serializable接口 oos.writeObject(zhangsan); oos.close(); System.out.println("序列化关闭"); } }
ObjectInputStream反序列化
package rcl; import java.io.FileInputStream; import java.io.ObjectInputStream; public class Demo07 { public static void main(String[] args) throws Exception { //1.创建对象流 FileInputStream fis=new FileInputStream("/Users/tomyoung/IdeaProjects/stu.bin"); ObjectInputStream ois=new ObjectInputStream(fis); //2.读取文件(反序列化操作) Student s1=(Student) ois.readObject(); //3.关闭 ois.close(); System.out.println(s1.toString()); } }
⚠️注意事项
序列化类必须实现Serializable接口
序列化类中的属性也要求实现Serializable接口
序列化版本ID,保证序列化的类和反序列化的类是同一个类。
使用transient修饰属性,这个属性不能序列化。
静态成员或者属性不能被序列化。
序列化多个对象,可以借助集合来实现。
ISO-8859-1收录除ASCII外,还包括西欧、希腊语、泰语、阿拉伯语、希伯来语对应的文字符号。
UTF-8针对Unicode码表的可变长度字符编码
GB2312简体中文
GBK简体中文、扩充
BIG5台湾、繁体中文
字符流的父类(抽象类):
Reader:字符输入流:
public int read(){}
public int read(char[] c){}
public int read(char[] b, int off,int len){}
Write:字符输出流:
public void write(int n){}
public void write(String str){}
public void write(char[] c){}
FileReader:
public int read(char[] c)//从流中读取多个字符,将读到内容存入c数组,返回实际读到的字符数;如果达到文件的尾部,则返回-1.
FileWrite:
public void write(String str)//一次写入多个字符,将b数组中所有字符,写入输出流。
FileReader
package rcl; import java.io.FileReader; public class Demo09 { public static void main(String[] args) throws Exception { //1.创建字符流 FileReader fr =new FileReader("/Users/tomyoung/IdeaProjects/aaa.txt"); //2.读取 //单个读取 // int data=0; // while((data=fr.read())!=-1){ // System.out.print((char)data); // } //自己创建字节缓冲区,多个读取 int count=0; char[] buf=new char[1024]; while((count=fr.read(buf))!=-1){ System.out.println(new String(buf,0,count)); } //关闭流 fr.close(); } }
FileWrite
package rcl; import java.io.FileWriter; public class Demo10 { public static void main(String[] args) throws Exception { //1.创建对象 FileWriter fw=new FileWriter("/Users/tomyoung/IdeaProjects/aaa.txt"); //2.写入 for(int i=0;i<10;i++){ fw.write("java是世界上最好的语言\r\n"); fw.flush(); } //3.关闭 fw.close(); } }
package rcl; import java.io.FileReader; import java.io.FileWriter; public class Demo11 { public static void main(String[] args) throws Exception { //只能复制文本文件,不能复制图片或者二进制文件 FileReader fr=new FileReader("/Users/tomyoung/IdeaProjects/aaa.txt"); FileWriter fw=new FileWriter("/Users/tomyoung/IdeaProjects/aaaa.txt"); //读写 int data=0; while((data=fr.read())!=-1){ fw.write(data); fw.flush(); } //3关闭 fr.close(); fw.close(); System.out.println("复制完毕"); } }
缓冲流:BufferedReader/BufferedWriter
高效读写
支持输入换行符。
可一次写一行、读一行
BufferedReader
package rcl; import java.io.BufferedReader; import java.io.FileReader; public class Demo12 { public static void main(String[] args) throws Exception { FileReader fr=new FileReader("/Users/tomyoung/IdeaProjects/aaa.txt"); BufferedReader br=new BufferedReader(fr); String line=null; while((line=br.readLine())!=null){ System.out.println(line);//一行行读取 } br.close(); } }
BufferedWriter
package rcl; import java.io.BufferedWriter; import java.io.FileWriter; public class Demo13 { public static void main(String[] args) throws Exception { FileWriter fw=new FileWriter("/Users/tomyoung/IdeaProjects/buffer.txt"); BufferedWriter bw=new BufferedWriter(fw); for(int i=0;i<10;i++){ bw.write("好好学习,天天向上"); bw.newLine(); bw.flush(); } bw.close(); } }
PrintWrite:
封装了print()/println()方法,支持写入后换行
支持数据原样打印
package rcl; import java.io.PrintWriter; public class Demo14 { public static void main(String[] args) throws Exception { //1.创建打印流 PrintWriter pw= new PrintWriter("/Users/tomyoung/IdeaProjects/bbb.txt"); //2.打印 pw.println(97); pw.println(3.14); pw.println(true); pw.println('a'); //3.关闭 pw.close(); } }
桥转换流:InputStreamReader/OutputStreamWriter
可以将字节流转换为字符流
可设置字符的编码方式。
package rcl; import java.io.FileInputStream; import java.io.InputStreamReader; public class Demo15 { public static void main(String[] args) throws Exception { FileInputStream fis=new FileInputStream("/Users/tomyoung/IdeaProjects/aaa.txt"); InputStreamReader isr=new InputStreamReader(fis,"UTF-8"); int data=0; while((data=isr.read())!=-1){ System.out.print((char)data); } isr.close(); } }
package rcl; import java.io.FileOutputStream; import java.io.OutputStreamWriter; public class Demo16 { public static void main(String[] args) throws Exception { FileOutputStream fos=new FileOutputStream("/Users/tomyoung/IdeaProjects/aaa.txt"); OutputStreamWriter osw=new OutputStreamWriter(fos,"UTF-8"); for(int i=0;i<10;i++){ osw.write("我爱长沙\r\n"); } osw.close(); } }
代表物理盘符中的一个文件或者文件夹。
方法:
createNewFile()//创建一个新文件
mkdir()//创建一个新目录
delete()//删除文件或空目录
exists()//判断File对象所代表的对象是否存在
getAbsolutePath()//获取文件的绝对路径
getName()//取得名字
getParent()//获取文件/目录所在的目录
isDirectory()//是否是目录
isFile()//是否是文件
length()//获得文件的长度
listFiles()//列出目录中的所有内容
renameTo()//修改文件名为
package wj; import java.io.File; public class Demo01 { public static void main(String[] args) { separator(); } public static void separator(){ System.out.println("路径分隔符"+ File.pathSeparator); System.out.println("名称分隔符"+File.separator); } } /* 输出结果: 路径分隔符: 名称分隔符/ */
package wj; import java.io.File; import java.util.Date; public class Demo01 { public static void main(String[] args) throws Exception { fileOpe(); } public static void fileOpe() throws Exception{ //1.创建文件 File f=new File("/Users/tomyoung/IdeaProjects/f.txt"); if(!f.exists()){ boolean b=f.createNewFile(); System.out.println(b); } //2.删除文件 //2.1 // boolean b1=f.delete(); // System.out.println(b1); //2.2,jvm退出时删除 // f.deleteOnExit(); // Thread.sleep(5000); //3.获取文件信息 System.out.println("获取文件绝对路径"+f.getAbsolutePath()); System.out.println("获取路径"+f.getPath()); System.out.println("获取文件名称"+f.getName()); System.out.println("获取父目录"+f.getParent()); System.out.println("获取文件长度"+f.length()); System.out.println("文件创建时间"+new Date(f.lastModified()).toLocaleString()); //4.判断 System.out.println("是否可写"+f.canWrite()); System.out.println("是否是文件"+f.isFile()); System.out.println("是否隐藏"+f.isHidden()); } } /* 输出结果: 获取文件绝对路径/Users/tomyoung/IdeaProjects/f.txt 获取路径/Users/tomyoung/IdeaProjects/f.txt 获取文件名称f.txt 获取父目录/Users/tomyoung/IdeaProjects 获取文件长度17 文件创建时间2021-11-25 20:05:31 是否可写true 是否是文件true 是否隐藏false */
package wj; import java.io.File; import java.util.Date; public class Demo01 { public static void main(String[] args) throws Exception { directory(); } public static void directory() throws Exception{ //1.创建文件夹 File dr= new File("/Users/tomyoung/IdeaProjects/aaa/ccc/bbb"); if(!dr.exists()){ //dr.mkdir();//只能创建单级目录 boolean b= dr.mkdirs();//只能创建多级目录 System.out.println(b); } //2.删除文件夹 //直接删除 // System.out.println("删除结果"+ dr.delete());//只删除对底层目录 // //jvm删除 // dr.deleteOnExit(); // Thread.sleep(5000); //3.获取文件夹信息 System.out.println("获取绝对路径"+dr.getAbsolutePath()); System.out.println("获取路径"+dr.getPath()); System.out.println("获取文件夹名称"+dr.getName()); System.out.println("获取父目录"+dr.getParent()); System.out.println("获取创建时间"+new Date(dr.lastModified()).toLocaleString()); //4.判断 System.out.println("是否是文件夹"+dr.isDirectory()); System.out.println("是否是隐藏"+dr.isHidden()); //5.遍历文件夹 File dr2=new File("/Users/tomyoung/IdeaProjects"); String[] s=dr2.list(); for(String string:s){ System.out.println(string); } } }
public interface FileFilter
Boolean accept(File pathname)
当调用File类中的listFiles()方法时,支持传入FileFilter接口接口实现类,对获取文件进行过滤,只有满足条件的文件才可以出现在listFile()的返回值中。
System.out.println("==================="); File[] f2=dr2.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { if(pathname.getName().endsWith("txt")) { return true; }else{ return false; } } }); for(File file:f2){ System.out.println(file.getName()); }
package dg; import java.io.File; public class Demo01 { public static void main(String[] args) { deleteDIr(new File("/Users/tomyoung/test")); } //案例1,递归遍历 public static void listDir(File dir){ File[] f=dir.listFiles(); System.out.println(dir.getAbsolutePath()); if(f!=null&&f.length>0){ for(File file:f){ if(file.isDirectory()){ listDir(file); }else{ System.out.println(file.getAbsolutePath()); } } } } //案例2,递归删除文件夹 public static void deleteDIr(File dir){ File[] f=dir.listFiles(); if(f!=null&&f.length>0){ for(File file:f){ if(file.isDirectory()){ deleteDIr(file); }else{ System.out.println(file.getAbsolutePath()+"删除"+file.delete()); } } } System.out.println(dir.getAbsolutePath()+"删除"+dir.delete()); } }
Properties:属性集合
特点
存储属性名和属性值
属性名和属性值都是字符串类型
没有泛型
和流有关
package dg; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.PrintWriter; import java.util.Properties; import java.util.Set; public class Demo02 { public static void main(String[] args) throws Exception { //1.创建集合 Properties p=new Properties(); //2.添加数据 p.setProperty("username","zhangsan"); p.setProperty("age","20"); System.out.println(p.toString()); //3.遍历 Set<String> p2=p.stringPropertyNames(); for(String s:p2){ System.out.println(s+"===="+p.getProperty(s)); } //4.和流有关的方法 // PrintWriter pw=new PrintWriter("/Users/tomyoung/IdeaProjects/bbb.txt"); // p.list(pw); // pw.close(); //store // FileOutputStream fos=new FileOutputStream("/Users/tomyoung/IdeaProjects/print.properties"); // p.store(fos,"注释"); // fos.close(); //load Properties p3=new Properties(); FileInputStream fis=new FileInputStream("/Users/tomyoung/IdeaProjects/print.properties"); p3.load(fis); fis.close(); System.out.println(p3.toString()); } }