Java SE09_I/O框架
2022/6/1 1:19:32
本文主要是介绍Java SE09_I/O框架,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
I/O 框架
1 流的概念
内存与存储设备之间传输数据的通道,数据借助流传输。
2 流的分类
按方向【重点】
- 输入流:将<存储设备>中的内容读到<内存>中
- 输出流:将<内存>中的内容写到<存储设备>中
按单位
- 字节流:以字节为单位,可以读写所有数据
- 字符流:以字符为单位,只能读写文本数据
按功能
- 节点流:具有实际传输数据的读写功能
- 过滤流:在节点流的基础之上增强功能
3 字节流
字节流的父类(抽象类)
//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){}
3.1 文件字节流
文件输入流代码演示:
public static void main(String[] args) throws Exception { /* * 演示FileInputStream的使用 * 文字字节输入流 */ //1.创建文件字节输出流并指定文件路径 FileInputStream fis =new FileInputStream("E:\\newstart\\linshi\\aaa.txt"); //2.读取文件 //2.1单个字节的读取 // int data = 0; // while((data = fis.read())!=-1){ // System.out.print((char)data);//abcdefg // } //2.2一次读取多个字节 // byte[] buf = new byte[3];//大小为3的缓存区 // int count = fis.read(buf);//一次读3个 // System.out.println(new String(buf));//abc // System.out.println(count);//3 //2.2优化之后 byte[] buf = new byte[3];//大小为3的缓存区 int count = 0; while ((count = fis.read(buf)) != -1) { System.out.print(new String(buf, 0, count)+" ");//abc def g } System.out.println(); //3.关闭 fis.close(); }
文件输出流代码演示:
public static void main(String[] args) throws Exception { /* * 演示FileOutputStream的使用 * 文字字节输出流 */ //1.创建文件字节输出流并指定文件路径,append=true时,可进行追加,不然会覆盖 FileOutputStream fos =new FileOutputStream("E:\\newstart\\linshi\\bbb.txt",true); //2.写入文件 //单个写入 String str = "hello world"; fos.write(str.getBytes()); //3.关闭 fos.close(); System.out.println("执行完毕"); }
3.2 文件复制案例
代码演示:
public static void main(String[] args) throws Exception { //文件的复制 //1.创建流 //输入流 FileInputStream fis = new FileInputStream("路径\\aaa.txt"); //输出流 FileOutputStream fos = new FileOutputStream("路径\\bbb.txt"); //2.一边读一边写 byte[] buf = new byte[1024]; int count = 0; while((count = fis.read(buf)) != -1){ fos.write(buf, 0, count); } //3.关闭 fis.close(); fos.close(); System.out.println("copy完毕"); }
3.3 字节缓冲流
缓冲流:BufferedInputStream/ BufferedOutputStream
- 提高IO效率,减少访问磁盘次数
- 数据存储在缓冲区中,flush是将缓冲区的内容写入文件中,也可以直接close
代码演示:
public static void main(String[] args) throws Exception { /** * 使用字节缓冲流读取 * BufferedInputStream */ //1.创建BufferedInputStream FileInputStream fis = new FileInputStream("E:\\newstart\\linshi\\aaa.txt"); BufferedInputStream bis = new BufferedInputStream(fis); //2.读取 //方法1(推荐) // int data = 0; // while ((data = bis.read()) != -1){ // System.out.print((char)data); // } //方法2 byte[] buf = new byte[1024]; int count = 0; while((count = bis.read(buf)) != -1){ System.out.println(new String(buf,0, count)); } //3.关闭 bis.close(); }
代码演示:
public static void main(String[] args) throws Exception { /** * 使用字节缓冲流写入数据 * BufferedOutputStream */ //1.创建字节输出缓冲流 FileOutputStream fos =new FileOutputStream("E:\\newstart\\linshi\\bbb.txt"); BufferedOutputStream bos = new BufferedOutputStream(fos); //2.写入文件 for (int i = 0; i < 10; i++) { bos.write("helloword\r\n".getBytes());//写入8k缓冲区 bos.flush(); // 刷新到硬盘 如果不flush(),关闭流之后也可以显示,但是刷新可以防止数据丢失 } //3.关闭(内部调用flush方法) bos.close(); }
4 对象流
ObjectOutputStream / ObjectInputStream
- 增强了缓冲区功能
- 增强了读写8种基本数据类型和字符串的功能
- 增强了读写对象的功能
readObject()
从流中读取一个对象writeObject(Object obj)
向流中写入一个对象
使用流传输对象的过程称为序列化、反序列化
理解:从内存写入文件到硬盘的过程称之为序列化,反之为反序列化。
4.1 序列化
代码演示:
public static void main(String[] args) throws Exception { /** * 使用ObjectOutputStream实现对象的序列化 * 要求:序列化的类必须实现Serializable接口,标记为可序列化的状态 */ //1.创建对象流 FileOutputStream fos = new FileOutputStream("E:\\newstart\\linshi\\stu.bin"); ObjectOutputStream oos = new ObjectOutputStream(fos); //2.序列化(写入操作) Student zs = new Student("张三", 20); oos.writeObject(zs); //3.关闭 oos.close(); System.out.println("序列化完毕"); }
4.2 反序列化
代码演示:
public static void main(String[] args) throws Exception { /** * 使用ObjectInputStream实现对象的反序列化(读取重构对象) */ //1.创建对象流 FileInputStream fis = new FileInputStream("E:\\newstart\\linshi\\stu.bin"); ObjectInputStream ois = new ObjectInputStream(fis); //2.读取文件(反序列化) Student stu = (Student) ois.readObject(); //3.关闭 ois.close(); System.out.println("反序列化完毕"); System.out.println(stu.toString());//Student{name='张三', age=20} }
4.3 注意事项
- 某个类要想序列化必须实现Serializable接口
- 序列化类中对象属性要求实现Serializable接口
- 序列化版本号ID:
serialVersionUID
,保证序列化的类和反序列化的类是同一个类 - 使用
transient
(瞬间的)修饰属性,这个属性就不能序列化 - 静态属性不能序列化
- 序列化多个对象,可以借助集合来实现
注:序列化版本号ID定义:private static final long serialVersionUID = 100L;
5 字符编码
- IS0-8859-1:收录除ASCII外,还包括西欧、希腊语、泰语、阿拉伯语、希伯来语对应的文字符号。
- UTF-8:针对Unicode码表的可变长度字符编码
- GB2312:简体中文
- GBK:简体中文、扩充
- BIG5:台湾,繁体中文
注:编码方式和解码方式不一致时,会出现乱码。
6 字符流
代码演示:
public static void main(String[] args) throws Exception { /** * 传统字节流读取 */ //1.创建FileInputStream对象 FileInputStream fis = new FileInputStream("E:\\newstart\\linshi\\hello.txt"); //2.读取 int data = 0; while((data = fis.read()) != -1){//12个字节 4个汉字 System.out.print((char)data); } //3.关闭 fis.close(); }
6.1 字符流的父类
reader
字符输入流
public int read(){}
public int read(char[] c){}
public int read(char[] b, int off, int len){}
Writer
字符输出流
public void write(int n){}
public void write(String str){}
public void write(char[] c){}
6.2 FileReader
文件字符输入流代码演示:
public static void main(String[] args) throws Exception { /** * 使用FileReader读取文件 */ //1.创建FileReader 文件字符输入流 FileReader fr = new FileReader("E:\\newstart\\linshi\\hello.txt"); //2.读取 //2.1单个字符读取 // int data = 0; // while ((data = fr.read()) !=-1){//读取一个字符 // System.out.print((char)data); // } //2.2字符缓冲区读取 char[] buf = new char[1024];//2的话一个2个字符 int count = 0; while ((count = fr.read(buf)) != -1){ System.out.println(new String(buf, 0, count)); } //3.关闭 fr.close(); }
6.3 FileWriter
文件字符输出流代码演示:
public static void main(String[] args) throws Exception { /** * 使用FileWriter写入文件 */ //1.创建FileWriter 文件字符输出流 FileWriter fw = new FileWriter("E:\\newstart\\linshi\\writer.txt"); //2.写入 for (int i = 0; i < 10; i++) { fw.write("java是世界上最好的语言\r\n"); fw.flush(); } //3.关闭 fw.close(); System.out.println("执行完毕"); }
6.4 文本文件复制(案例)
使用FileReader
和FileWriter
不能复制图片或二进制文件,使用字节流可以复制任意文件
代码演示:
public static void main(String[] args) throws Exception { //1.创建 FileReader fr = new FileReader("E:\\newstart\\linshi\\writer.txt"); FileWriter fw = new FileWriter("E:\\newstart\\linshi\\w.txt"); //2.读写 int data = 0; while ((data = fr.read()) != -1){ fw.write(data); fw.flush(); } //3.关闭 fr.close(); fw.close(); System.out.println("copy完毕"); }
6.5 字符缓冲流
BufferedReader / BufferedWriter
高效读写、支持输入换行符、可一次写一行读一行
代码演示:
public static void main(String[] args) throws Exception { /** * 使用字符缓冲流读取文件 * BufferdReader */ //1.创建缓冲流 FileReader fr = new FileReader("E:\\newstart\\linshi\\writer.txt"); BufferedReader br = new BufferedReader(fr); //2.读取 //2.1 第一种方式 char[] buf = new char[1024]; int count = 0; while((count = br.read(buf)) != -1){ System.out.print(new String(buf, 0, count)); } //2.2 第二种方式 一行一行读 String line = null; while((line = br.readLine()) != null){ System.out.print(line); } //3.关闭 br.close(); }
代码演示:
public static void main(String[] args) throws Exception { /** * 使用字符缓冲流写入文件 * BufferedWriter */ //1.创建缓冲流 FileWriter fw = new FileWriter("E:\\newstart\\linshi\\buf.txt"); BufferedWriter bw = new BufferedWriter(fw); //2.写入 for (int i = 0; i < 10; i++) { bw.write("好好学习。"); bw.newLine();//写入一个换行符 bw.flush(); } //3.关闭 bw.close(); System.out.println("执行完毕"); }
7 打印流
7.1 PrintWriter
封装了print() / println()
方法 支持写入后换行
支持数据原样打印
代码演示:
public static void main(String[] args) throws Exception { /** * 演示PrintWriter的使用 */ //1.创建一个打印流 PrintWriter pw = new PrintWriter("E:\\newstart\\linshi\\print.txt"); //2.打印 pw.println(97); pw.println(true); pw.println(3.14); pw.println("你好nihao"); //3.关闭 pw.close(); System.out.println("执行完毕"); }
8 转换流
桥转换流 InputStreamReader / OutputStreamWriter
可将字节流转换为字符流
可设置字符的编码方式,通常使用UTF-8,文件另存为ANSI就是gbk
代码演示:
public static void main(String[] args) throws Exception { /** * 使用InputStreamReader读取文件 指定使用的编码 */ //1.创建InputStreamReader对象 FileInputStream fis = new FileInputStream("E:\\newstart\\linshi\\writer.txt"); InputStreamReader isr = new InputStreamReader(fis, "utf-8"); //2.读取文件 int data = 0; while ((data = isr.read()) != -1){ System.out.print((char)data); } //3.关闭 isr.close(); }
代码演示:
public static void main(String[] args) throws Exception { /** * 使用OutputStreamWriter 写入文件 指定使用的编码 */ //1.创建OutputStreamWriter对象 FileOutputStream fos = new FileOutputStream("E:\\newstart\\linshi\\writer.txt"); OutputStreamWriter osw = new OutputStreamWriter(fos, "utf-8"); //2.写入文件 for (int i = 0; i < 10; i++) { osw.write("我爱北京\r\n"); osw.flush(); } //3.关闭 fos.close(); System.out.println("执行完毕"); }
9 File类
概念:代表物理盘符中的一个文件或者文件夹
9.1 四个常量
1.public static final char separatorChar; 与系统有关的默认名称分隔符。 此字段被初始化为包含系统属性file.separator 值的第一个字符。在 UNIX 系统上,此字段的值为 '/';在 Microsoft Windows 系统上,它为 '\\'。 2.public static final String separator; 与系统有关的默认名称分隔符,为了方便,它被表示为一个字符串。 此字符串只包含一个字符,即 separatorChar。 3.public static final char pathSeparatorChar; 与系统有关的路径分隔符。 此字段被初始为包含系统属性 path.separator 值的第一个字符。此字符用于分隔以路径列表 形式给定的文件序列中的文件名。在 UNIX 系统上,此字段为 ':';在 Microsoft Windows 系统上,它为 ';'。 4.public static final String pathSeparator; 与系统有关的路径分隔符,为了方便,它被表示为一个字符串。 此字符串只包含一个字符,即 pathSeparatorChar。
9.2 常用方法
- 获取文件或目录的详细信息
String getName(): 返回由此抽象路径名表示的文件或目录的名称。 long length() : 返回由此抽象路径名表示的文件的长度。(只能返回文件大小,不能直接返回目录大小) boolean exists() : 判断此抽象路径名表示的文件或目录是否存在。 boolean isHidden() : 判断此抽象路径名指定的文件是否是一个隐藏文件。 boolean canRead() : 判断应用程序是否可以读取此抽象路径名表示的文件。 boolean canWrite() : 判断应用程序是否可以修改此抽象路径名表示的文件 long lastModified() : 返回此抽象路径名表示的文件最后一次被修改的时间。(毫秒值) String toString() : 返回此抽象路径名的路径名字符串。boolean isAbsolute(): 测试File对象对应的文件或目录是否是绝对路径。 String getParent() : 返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回 null。(返回父目录名称) File getParentFile() :返回此抽象路径名父目录的抽象路径名;如果此路径名没有指定父目录,则返回 null。(返回父目录的File对象)
- 获取文件或目录的路径
String getPath() : 将此抽象路径名转换为一个路径名字符串。 File getAbsoluteFile() : 返回此抽象路径名的绝对路径名形式。 String getAbsolutePath():返回此抽象路径名的绝对路径名字符串。 返回绝对路径,从根目录开始导航 File getCanonicalFile(): 返回此抽象路径名的规范形式。 String getCanonicalPath() :返回此抽象路径名的规范路径名字符串。规范路径就是路径里没有./或../或/,会把这些自动解析
- 操作文件或目录
boolean createNewFile():当且仅当不存在具有此抽象路径名指定名称的文件时,不可分地创建一个新的空文件。(只创建文件) boolean delete(): 删除此抽象路径名表示的文件或目录。(可以删除文件或删除空目录)删除成功,返回true,失败false。 boolean equals(Object obj):判断此抽象路径名与给定对象是否相等。 boolean mkdir() : 创建此抽象路径名指定的目录。(只能创建一级目录)必须确保父目录存在,否则创建失败。 boolean mkdirs(): 创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。 (可以创建多级目录)如果父目录不存在,会一同创建父目录 boolean renameTo(File dest) :重新命名此抽象路径名表示的文件。(可以给文件或目录重命名)
- 判断是文件还是目录
boolean isFile() :判断此抽象路径名表示的文件是否是一个标准文件。 boolean isDirectory():判断此抽象路径名表示的文件是否是一个目录。
- 获取目录的下一级
String[] list() :返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。 File[] listFiles() :返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。(获取下一级的文件/目录的File对象) static` `File[] listRoots():列出可用的文件系统根。
9.3 案例(基本以及FileFilter过滤器)
代码演示:
public static void main(String[] args) throws Exception { /** * File类的使用 * (1)分隔符 * (2)文件操作 * (3)文件夹操作 */ // separator(); // fileOpe(); directoryOpe(); } //(1)分隔符 public static void separator(){ System.out.println("路径分隔符" + File.pathSeparator);//; System.out.println("名称分隔符" + File.separator);//\ } //(2)文件操作 public static void fileOpe() throws Exception { //1.创建文件 File file = new File("E:\\newstart\\linshi\\file\\file.txt"); // System.out.println(file.toString());//E:\newstart\linshi\file\file.txt if(!file.exists()){//判断是否存在 boolean b = file.createNewFile(); System.out.println("创建结果:" + b); } //2.删除文件 //2.1直接删除 // boolean delres = file.delete(); // System.out.println("删除结果:"+delres); //2.2使用jvm退出时删除 // file.deleteOnExit(); // Thread.sleep(5000);//休眠5秒,方便看效果 //3.获取文件信息 System.out.println("获取文件的绝对路径:" + file.getAbsolutePath()); System.out.println("获取路径:" + file.getPath()); System.out.println("获取文件名称:" + file.getName()); System.out.println("获取父目录:" + file.getParentFile()); System.out.println("获取文件长度:" + file.length());//汉字占3个 System.out.println("文件创建时间:" + new Date(file.lastModified()).toLocaleString());//lastModified()默认是long类型 //4.判断 System.out.println("是否可写:" + file.canWrite()); System.out.println("是否是文件:" + file.isFile()); System.out.println("是否是隐藏:" + file.isHidden()); } //(3)文件夹操作 public static void directoryOpe() throws Exception { //1.创建文件夹 File dir = new File("E:\\newstart\\linshi\\file1"); System.out.println(dir.toString()); if(!dir.exists()){ dir.mkdirs();//mkdir()只能创建单级目录 } //2.删除文件夹 //2.1直接删除 // boolean delres = dir.delete();//只能删除空目录 // System.out.println("删除结果:"+delres); //2.2使用jvm退出时删除 // dir.deleteOnExit(); // Thread.sleep(5000);//休眠5秒,方便看效果 //3.获取文件信息 System.out.println("获取文件夹的绝对路径:" + dir.getAbsolutePath()); System.out.println("获取文件夹路径:" + dir.getPath()); System.out.println("获取文件夹名称:" + dir.getName()); System.out.println("获取父目录:" + dir.getParentFile()); System.out.println("文件夹创建时间:" + new Date(dir.lastModified()).toLocaleString());//lastModified()默认是long类型 //4.判断 System.out.println("是否是文件夹:" + dir.isDirectory()); System.out.println("是否是隐藏:" + dir.isHidden()); //5.遍历文件夹 File dir2 = new File("E:\\newstart\\linshi"); String[] files = dir2.list();//listFiles()返回File类型,list返回String类型 for (String file : files) { System.out.println(file); } //FileFilter接口的使用(文件过滤器) System.out.println("--------FileFilter接口的使用--------"); File[] files2 = dir2.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { if (pathname.getName().endsWith(".png")) { return true; } return false; } }); for (File file : files2) { System.out.println(file.getName()); } }
9.4 递归遍历
代码演示:
//案例1 递归遍历文件夹 public static void listDir(File dir) throws Exception { File[] files = dir.listFiles(); System.out.println(dir.getAbsoluteFile()); if(files != null && files.length > 0) { for (File file : files) { if(file.isDirectory()) { listDir(file); }else{ System.out.println(file.getAbsolutePath()); } } } }
9.5 递归删除
代码演示:
//案例2 递归删除文件夹 public static void delDir(File dir) throws Exception { File[] files = dir.listFiles(); if(files != null && files.length > 0) { for (File file : files) { if(file.isDirectory()) { delDir(file); }else{ System.out.println(file.getAbsolutePath()+"删除:"+file.delete()); } } } System.out.println(dir.getAbsolutePath()+"删除:"+dir.delete());//删除文件夹 }
10 Properties
集合中提到过
Properties:属性集合,继承hashtable,线程安全
特点:
- 存储属性名和属性值
- 属性名和属性值都是字符串类型
- 没有泛型
- 和流有关
代码演示:
public static void main(String[] args) throws Exception { /** * 演示Properties集合的使用 */ //1.创建集合 Properties properties = new Properties(); //2.添加元素 properties.setProperty("name", "张三"); properties.setProperty("age", "20"); System.out.println(properties.toString()); //3.删除 remove() clear() //4.遍历 //4.1 keySet //4.2 entrySet //4.3 stringPropertyNames() Set<String> strings = properties.stringPropertyNames(); for (String string : strings) { System.out.println(string+":"+properties.getProperty(string)); } //5.和流有关的方法 //5.1 list() // PrintWriter pw = new PrintWriter("E:\\newstart\\linshi\\print.txt"); // properties.list(pw); // pw.close(); //5.2 store() 保存 //可以使用FileOutputStream和FileInputStream(中文乱码会乱码),也可以使用FileWriter和FileReader(中文不乱码) // FileWriter fw = new FileWriter("E:\\newstart\\linshi\\print.propertes"); // properties.store(fw,"注释"); // fw.close(); //5.3 load() 加载 Properties properties2 = new Properties(); FileReader fr = new FileReader("E:\\newstart\\linshi\\print.propertes"); properties2.load(fr); fr.close(); System.out.println(properties2.toString()); }
总结
流的概念:
- 内存与存储设备之间传输数据的通道。
流的分类:
- 输入流、输出流;字节流、字符流;节点流、过滤流;
序列化、反序列化:
- 将对象通过流写入到文件,或将对象通过流读取到内存,必须实现Serializable接口。
File对象:
- 代表物理盘符中的一个文件或者文件夹。
END
这篇关于Java SE09_I/O框架的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-26消息中间件源码剖析教程
- 2024-11-26JAVA语音识别项目资料的收集与应用
- 2024-11-26Java语音识别项目资料:入门级教程与实战指南
- 2024-11-26SpringAI:Java 开发的智能新利器
- 2024-11-26Java云原生资料:新手入门教程与实战指南
- 2024-11-26JAVA云原生资料入门教程
- 2024-11-26Mybatis官方生成器资料详解与应用教程
- 2024-11-26Mybatis一级缓存资料详解与实战教程
- 2024-11-26Mybatis一级缓存资料详解:新手快速入门
- 2024-11-26SpringBoot3+JDK17搭建后端资料详尽教程