IO流
1.什么是流
-
概念:内存与存储设备之间传输数据的通道。
-
存储设备<---->内存<--->存储设备
2.流的分类
-
按方向:
-
输入流:将存储设备中的内容读取到内存中
-
输出流:将内存中的内容写入到存储设备中
-
-
按单位:
-
字节流:以字节为单位,可以读写所有数据
-
字符流:以字符为单位,只能读写文本数据
-
-
按功能:
-
节点流:具有实际传输数据的读写功能
-
过滤流:在节点流的基础上增强功能
-
3.字节流
-
字节流的父类(抽象类)
-
InputStream:字节输入流
read();
read(byte[] b);
read(byte[] b,int off,int len)
-
OuputStream:字节输出流
write(int n);
write(byte[] b);
write(byte[] b,int off,int len)
-
-
字节流的子类
-
FileInputStream:
-
read(byte[] b) //从流中读取多个字节,将读到内容存到b数组,返回实际读到的字节数;如果达到文件的尾部,则返回-1。
-
代码
public class Demo01 { public static void main(String[] args) throws IOException { //1.创建FileInputStream,并指定文件路径 FileInputStream fis = new FileInputStream("d:\\sy.txt"); //2.读取文件 //fis.read(): //2.1 单个字节读取(读一个打印一次,执行效率较慢) // int date=0; // while((date=fis.read())!=-1){ // System.out.println(date); // } //2.2 多个字节读取 byte[] buffer = new byte[1024]; int count=0; while((count=fis.read(buffer))!=-1){ System.out.println(new String(buffer,0,count)); } //3.关闭流 fis.close(); System.out.println("读取完毕"); } }
-
-
FileOutputStream:
-
write(byte[] b) //一次写多个字节,将b数组中所有字节,写入输出流。
-
代码
public class Demo02 { public static void main(String[] args) throws Exception { ///1.创建文件字节输出流文件 FileOutputStream fos = new FileOutputStream("d:\\hh.txt",true);//加true每运行一次就重复写入文件 //2.写入文件 String str="hha"; fos.write(str.getBytes());//获得字符串所对应的字节数组 //3.关闭流 fos.close(); System.out.println("执行完毕"); } }
-
-
-
字节流复制文件
-
代码
//使用文件字节流实现文件的复制 public class Demo03 { public static void main(String[] args) throws Exception { //1.创建文件字节输入流 FileInputStream fis = new FileInputStream("d:\\hh.jpg"); //2.创建文件字节输出流 FileOutputStream fos = new FileOutputStream("d:\\huanghao.jpg"); //3.一边读,一边写 byte[] buffer = new byte[1024]; int count; while((count=fis.read(buffer))!=-1){ fos.write(buffer,0,count); } System.out.println("执行完毕"); } }
-
-
字节缓冲流
-
缓冲流:BufferedInputStream/BufferedOutputStream
-
提高IO效率,减少访问磁盘的次数
-
数据存储在缓冲区中,flush是将缓冲区的内容写入文件中,也可以直接close。
-
代码
//使用字节缓冲流读取文件 public class Demo04 { public static void main(String[] args) throws Exception { //1.创建文件字节缓冲流 FileInputStream fis = new FileInputStream("d:\\hh.txt"); //2.创建字节缓冲流 BufferedInputStream buf = new BufferedInputStream(fis); //3.读取 // //3.1 直接缓冲流读取 // int date=0; // while((date=buf.read())!=-1){ // System.out.println((char)date);//直接打印date是打印ASC码值(转类型成char) // } //3.2 创建一个缓冲区 byte[] buffer = new byte[1024]; int count=0;//计数器 while((count=buf.read(buffer))!=-1){ System.out.println(new String(buffer,0,count)); } //4.关闭 buf.close(); System.out.println("执行完毕"); } } //使用字节缓冲流写入文件 public class Demo05 { public static void main(String[] args) throws Exception { //1.创建字节缓冲流 FileOutputStream fis = new FileOutputStream("d:\\Msshen.txt"); BufferedOutputStream bos = new BufferedOutputStream(fis); //2.写入 for(int i=0;i<10;++i){ bos.write("I want you back\r\n".getBytes()); bos.flush();//刷新到内存 } //3.关闭流(内部使用flush方法) bos.close(); } }
-
-
4.对象流
-
对象流:ObjectOutputStream/ObjectInputStream
-
增强了缓冲区功能
-
增强了读写八种基本数据类型和字符串功能
-
增强了读写对象的功能:
-
readObject() 从流中读取一个对象
-
writeObject(Object obj) 向流中写入一个对象
-
-
-
使用流传输对象的过程称为序列化、反序列化。
-
代码
/* 1.序列化类必须要实现Serializable接口 2.序列化类中对象属性也要实现Serializable接口 3.SerializableUID:版本序列号ID 4.序列化版本号ID,保证序列化的类与反序列化的类是同一个类 5.使用transient修饰属性,不能被序列化 6.静态属性不能被序列化 7.序列化多个对象,用集合 */ public class Student implements Serializable {//此处注意,序列化类必须要实现序列化的接口 private static final long SerializableUID=100l; String name; int age; public Student() {//无参构造 } public Student(String name, int age) {//有参构造 this.name = name; this.age = age; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public int getAge() { return age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } } //使用ObjectOutputStream实现对象的序列化 public class Demo06 { public static void main(String[] args) throws Exception { //1.创建对象流 FileOutputStream fos = new FileOutputStream("D:\\king.bin"); ObjectOutputStream oos = new ObjectOutputStream(fos); //2.序列化(写入操作) Student stu = new Student("zhangsan",18); Student stu2=new Student("lisi",56); ArrayList<Student> list=new ArrayList<>();//集合 list.add(stu); list.add(stu2); oos.writeObject(list); //关闭流 oos.close(); System.out.println("序列化完毕"); } } //使用ObjectInputStream实现反序列化(读取重构成对象) public class Demo07 { public static void main(String[] args) throws Exception { //1.创建对象流 FileInputStream fis = new FileInputStream("d:\\king.bin"); ObjectInputStream ois = new ObjectInputStream(fis); //2.读取 // Student stu = (Student)ois.readObject(); ArrayList<Student> list=(ArrayList<Student>) ois.readObject(); System.out.println(list.toString()); //3.关闭流 ois.close(); System.out.println("反序列化完毕"); } }
5.字符编码
-
UTF-8: 针对Unicode码表的可变长度字符编码
-
GB2312: 简体中文
-
GBK: 简体中文、扩充
-
BIG5: 台湾,繁体中文
-
当编码方式与解码方式不一致时,会出现乱码
6.字符流
-
字符流的父类(抽象类):
-
Reader:字符输入流
-
read()
-
read(char[] c)
-
read(char[] b, int off, int len)
-
-
Writer:字符输出流
-
write(int n)
-
write(String str)
-
write(char[] c)
-
-
-
文件字符流
-
FileReader:
-
read(char[] c) //从流中读取多个字符,将读到内容存到c数组,返回实际读到的字符数;如果达到文件的尾部,则返回-1.
-
代码
/使用文件字符流FileReader 实现 public class Demo01 { public static void main(String[] args) throws Exception { //1.创建文件字符流 FileReader fr = new FileReader("D:\\hh.txt"); //2.读取 //2.1 单个字符读取 // int date=0; // while((date=fr.read())!=-1){ // System.out.println((char)date); // } //2.2 创建一个缓冲区,多个字符一次读取 char[] buffer = new char[1024]; int len=0; while((len=fr.read(buffer))!=-1){ System.out.println(new String(buffer,0,len)); } //3.关闭流 fr.close(); System.out.println("读取完毕"); } }
-
-
FileWriter:
-
write(String str) //一次写多个字符,将b数组中所有字符,写入输出流。
-
-
使用FileReader和FileWriter复制文本文件,不能复制图片或二进制文件。
-
使用字节流复制任意文件。
-
代码
//使用FileWriter写入文件 public class Demo02 { public static void main(String[] args) throws Exception { //1.创建FileWriter对象 FileWriter fw = new FileWriter("d:\\hh.txt"); //2.写入 for (int i = 0; i < 10; i++) { fw.write("不要离开\r\n"); fw.flush(); } //3.关闭流 fw.close(); System.out.println("写入文件完毕"); } }
-
-
字符缓冲流
BufferedReader/BufferedWriter
-
高效读写
-
支持输入换行符
-
可一次写一行,读一行
-
代码
//使用字符缓冲流读取文件 public class Demo03 { public static void main(String[] args) throws Exception { //1.创建缓冲流 FileReader fr = new FileReader("d:\\hh.txt"); BufferedReader br = new BufferedReader(fr); //2.读取 // //2.1 第一种方式 // char[] buffer = new char[1024]; // int len=0; // while((len=br.read(buffer))!=-1){ // System.out.println(new String(buffer,0,len)); // } //2.2 第二种方式,一行一行的读 String date=null; while((date=br.readLine())!=null){ System.out.println(date); } //3.关闭流 br.close(); } } //使用字符缓冲写入文件 public class Demo04 { public static void main(String[] args) throws Exception { //1.创建缓冲流 FileWriter fw = new FileWriter("d:\\sy.txt"); BufferedWriter bw = new BufferedWriter(fw); //2.写入 for (int i = 0; i < 10; i++) { bw.write("入目无别人"); bw.newLine();//换行(在windows系统中换行是\r\n,在linux系统中是\n) bw.flush(); } //3.关闭 bw.close(); } }
-
-
打印流
-
PrintWriter:
-
封装了print()/println()方法,支持写入后换行
-
支持数据原样打印
-
例如:数字,布尔类型、double
-
-
-
转换流
-
桥转换流:InputStreamReader/OuputStreamWriter
-
可将字节流(硬盘)转换成字符流(内存)
-
可设置字符的编码方式
-
代码
//使用InputStreamReader读取文件 使用指定的编码 public class Demo05 { public static void main(String[] args) throws Exception { //1.创建InputStreamReader FileInputStream fis = new FileInputStream("d:\\hh.txt"); InputStreamReader isr = new InputStreamReader(fis,"utf-8"); //2.读取 char[] buffer = new char[1024]; int len=0; while((len=isr.read(buffer))!=-1){ System.out.println(new String(buffer,0,len)); } //3.关闭 isr.close(); } } //使用OuputStreamWriter写入文件,使用指定的编码 public class Demo06 { public static void main(String[] args) throws Exception { //1.创建OuputStreamWriter FileOutputStream fos = new FileOutputStream("d:\\out.txt"); OutputStreamWriter osw = new OutputStreamWriter(fos,"gbk"); //2.写入,以指定的编码 for (int i = 0; i < 10; i++) { osw.write("人总要跟握不住的东西说再见"); osw.flush(); } //3.关闭 osw.close(); } }
-
-
7.File类
-
概念:代表物理盘符中的一个文件或者文件夹
-
方法:
-
createNewFile()//创建一个新文件
-
mkdir()//创建一个新目录
-
delete()//删除文件或空目录
-
exists()//判断File对象所代表的对象是否存在
-
代码
/* File类的操作 1.分隔符 2.文件 3.文件夹 */ public class Demo01 { public static void main(String[] args) throws Exception { // separator(); fileOpe(); } //1.分割符 public static void separator(){ System.out.println("路径分隔符"+ File.pathSeparator); System.out.println("名称分隔符"+File.separator); } //2.文件操作 public static void fileOpe() throws Exception { //1.创建文件 createFile() File file = new File("d:\\file.txt"); //判断File是否存在 if(!file.exists()){ Boolean b=file.createNewFile(); System.out.println("创建结果:"+b); } //2.删除文件 // //2.1 file提供的方法 // boolean d = file.delete(); // System.out.println("删除结果:"+d); // //2.2 由JVM退出时删除file // file.deleteOnExit(); // Thread.sleep(5000); //3.文件操作 System.out.println("获取文件绝对路径:"+file.getAbsolutePath()); System.out.println("获取文件路径:"+file.getPath()); System.out.println("获取文件名称:"+file.getName()); System.out.println("获取文件父目录:"+file.getParent()); System.out.println("获取文件长度:"+file.length());//以UTF-8方式编码时,一个汉字占三个字节 System.out.println("文件创建时间:"+new Data(file.lastModified()).toLocalString); //4.判断 System.out.println("是否可写:"+ file.canWrite()); System.out.println("是否是文件:"+file.isFile()); System.out.println("是否隐藏:"+file.isHidden()); } // } //创建文件夹的操作 public class Demo02 { public static void main(String[] args) throws Exception { directroyOpe(); } public static void directroyOpe () throws Exception{ //1.创建文件夹 File dir = new File("d:\\aaa\\bbb\\ccc"); // dir.mkdir();//只能创建单级文件夹 if(!dir.exists()){ System.out.println("文件夹创建"+dir.mkdirs());//创建多级目录 } //2.删除文件夹 //2.1直接删(只能删除最底层文件夹,且是空文件夹) // System.out.println("删除结果:"+dir.delete()); //2.2 由JVM删 // System.out.println("删除结果:"+dir.deleteOnExit()); //3.文件夹操作 System.out.println("文件夹的绝对路径:"+dir.getAbsolutePath()); System.out.println("文件夹的路径:"+dir.getPath()); System.out.println("文件夹的父目录:"+dir.getParent()); System.out.println("文件夹的名字:"+dir.getName()); System.out.println("文件夹的创建时间:"+new Date(dir.lastModified()).toLocaleString()); //4,判断 //System.out.println("是否可写:"+dir.canWrite()); System.out.println("文件是否隐藏:"+dir.isHidden()); System.out.println("文件夹是否是文件夹"+dir.isDirectory()); //5.遍历文件夹 File dir2 = new File("d:\\约拍照片"); String[] list = dir2.list(); for (String s : list) { System.out.println("D盘文件:"+s); } //FileFilter的使用 File[] files=dir2.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { if (pathname.getName() .endsWith(".jpg")) { return true; } return false; } }); for (File file : files) { System.out.println(file); } } }
-
-
两个案例
public class ListDemo { public static void main(String[] args) { listDir(new File("d:\\myfiles")); } //案例1:递归遍历文件夹 public static void listDir(File dir) { File[] files = dir.listFiles(); System.out.println(dir.getAbsolutePath()); if(files!=null&&files.length>0){ for (File file : files) { if (file.isDirectory()){ listDir(file);//递归 }else{ System.out.println(file.getAbsolutePath()); } } } } //案例2:递归删除文件夹 public static void deleteDir(File dir) { File[] files = dir.listFiles(); if(files!=null&&files.length>0){ for (File file : files) { if (file.isDirectory()) { deleteDir(file);//递归 }else{ //删除文件 System.out.println(file.getAbsolutePath()); } } } System.out.println(dir.getAbsolutePath()+"删除"+dir.delete()); } }
8.FileFilter接口
-
public interface FileFilter
-
boolean accept(File pathname)
-
-
当调用File类中的ListFiles()方法时,支持传入FileFilter接口接口实现类,对获取文件进行过滤,只有满足条件的文件才可以出现在listFiles()的返回值中
9.补充:Properties
-
Properties:属性集合
-
特点:
-
存储属性名和属性值
-
属性名和属性值都是字符串类型
-
没有泛型
-
和流有关
-
-
代码
//测试Properties public class Demo03 { public static void main(String[] args) throws IOException { //1.创建集合 Properties properties = new Properties(); //2.添加数据 properties.setProperty("username","hh"); properties.setProperty("age","20"); System.out.println(properties.toString()); //3.遍历 //3.1 keySet //3.2 entrySet //3.3 stringPropertyNames() Set<String> pronames=properties.stringPropertyNames(); for (String s : pronames) { System.out.println(s+"---"+properties.getProperty(s)); } //4.和流有关的方法 //list方法 PrintWriter pw = new PrintWriter("d:\\print.txt"); properties.list(pw); pw.close(); //2.store方法保存 FileOutputStream fos = new FileOutputStream("d:\\store.properties"); properties.store(fos,"注释"); fos.close(); //3.load方法加载 Properties properties2 = new Properties(); FileInputStream fis = new FileInputStream("d:\\store.properties"); properties2.load(fis); fis.close(); System.out.println(properties2.toString()); } }