12、IO流
IO流
File类
file是文件的意思,所以他是一个可以获取磁盘上的文件的信息,比如说文件的大小(字节单位),文件的相对路径,绝对路径,可读可写,删除文件,获得文件名等操作。
构造方法:
File(String name);// "d:/text.txt"
File(URI uri);
File(目录,子目录);
方法:
方法名称 | 说 明 |
---|---|
boolean exists( ) | 判断文件或目录是否存在 |
boolean isFile( ) | 判断是否是文件 |
boolean isDirectory( ) | 判断是否是目录 |
String getPath( ) | 返回此对象表示的文件的相对路径名 |
String getAbsolutePath( ) | 返回此对象表示的文件的绝对路径名 |
String getName( ) | 返回此对象表示的文件或目录的名称 |
boolean delete( ) | 删除此对象指定的文件或目录 |
boolean createNewFile( ) | 创建名称的空文件,不创建文件夹 |
long length() | 返回文件的长度,单位为字节****, 如果文件不存在,则返回 0L |
public class Test{ main{ File file = new File("d:/test/text.txt");//创建文件对象 if(!file.exists){//判断是否存在,有目录的时候就不会自动 创建,取反了 file.mkdir();创建目录,只会创建一层目录,如果有多层则不会创建。 file.mkdirs();创建目录,有多层就会创建多层。 } file.getName();获取文件的名字。 file.delect();删除file的整个文件 file.geAbsolutePath();获得绝对路径。 file.getPath();获得相对路径。 file.createNewFile();创建一个文件 file.toURI();获得浏览器可以访问的路径。 file.length();获取文件名的长度,不存在返回0L } }
InputStream:输入流 和 OutputStream:输出流
两者是字节的输入输出流,也叫节点流。直接跟磁盘链接,每次读写都是一个字节。磁盘的存储单位是字节。
对于输入输出的概念:我们是以当前程序作为参照物,从磁盘向程序中读数据,是输入。从程序写到磁盘上为输出流。
是一个抽象类,用子类来进行对磁盘的操作。
FileInputStream 和 FileOutputStream:
FileInputStream 文件的输入流,主要是对文件的内容进行读取。
FileOutputStream 文件的输出流,主要是将内容从程序写到磁盘上
package file; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class Demo { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("D:\\我的青春我做主.txt");//创建输入流对象,括号里面是一个文件的对象 /** *同过byte[]数组进行读取,每次都读byte数组那么多次效率就高了, *而不是每次只读取一个,效率极低 */ byte[] bs = new byte[500]; int len = fis.read(bs); //创建文件对象,获取到磁盘上的文件 File fl = new File("E:\\myFile"); fl.mkdirs();//已经判断了是否存在,如果不存在会自动创建一个 File file = new File(fl,"myPrime.txt"); if(!file.exists()) { System.out.println("...."); file.createNewFile(); } System.out.println(file.getAbsolutePath()); System.out.println(file.getName()); //创建文件的输出流,将内容写进file里面。 FileOutputStream fos = new FileOutputStream(file); fos.write(bs,0,len);//也是通过byte数组进行写入,0是从byte数组的0个位置写入len的字节数 //到最后不要忘记关闭流,不关闭流会导致占用内存,倒着关 fos.close(); fis.close(); } }
Reader:读 和 Writer:写
每次读取的是一个字符(两个字节的结合),也是直接跟数据源进行传输的,可以称为节点流,
但是从数据源传输到程序的时候将两个字符结合成一个字符了,存在缓冲区,而写的时候是将一个字符先变成两个字节在传输到磁盘上,所以也可以称为处理流。
因为存在缓冲区,所以在写的时候需要通过flush()将缓冲区的内容提交到磁盘上,不然等程序运行结束的时候,因为内容还存在缓冲区中还没进行写入缓冲区的时候进释放内存了。
也可以通过close()关闭流的时候也会提交一次。
FileReader 和 FileWriter
二者的基类是 InuputStreamReader 和 OutputStreamWriter
是文件的字符输入输出流,每次读取的是一个字符。
package demo; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class Demo { public static void main(String[] args) throws IOException { FileReader fr = new FileReader("e:/my.txt");//创建一个读的对象 char[] ch = new char[1024];//通过一个字符数组来传输,每次可以读1024个 int len = 0;//接收读到了多少个字符 while((len = fr.read(ch)) != -1) {//读取的字符数,如果已到达流的末尾,则返回 -1 System.out.println(new String(ch,0,len));//输出在控制台 } FileWriter fw = new FileWriter("e:/my.txt");//创建一个写的流 fw.write("我和我的祖国");//写进缓冲区,也可以将一个字符数组写进去 fw.flush();//不调用这个方法就不会从缓冲区写进磁盘, //关闭流 fw.close(); fr.close(); } }
BufferedReader 和 BufferedWriter
创建一个字符的缓冲区,是为了提高读和写的效率。
是一个处理流来的。
package demo; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class Demo07 { public static void main(String[] args) throws IOException { File file = new File("e:/my.txt"); if(!file.exists()) { file.createNewFile(); } FileWriter fw = new FileWriter(file); //通过writer来创建字符缓冲区对象 BufferedWriter bw = new BufferedWriter(fw); String str = "《虞美人》-春花秋月何时了? -往事知多少。- 小楼昨夜又东风," + "-故国不堪回首月明中。-雕栏玉砌应犹在,- 只是朱颜改。-" + "问君能有几多愁?-恰似一江春水向东流。"; String [] strs = str.split("-"); for (String string : strs) { bw.write(string);//每次写一行进去 bw.newLine();//换行,到下一行 bw.flush();//刷新缓冲区,放在这里的原因是每次写完一行进从缓冲取里提交一次,就不会造成缓冲区的扩充,而在然后面再去写进磁盘,大大提高效率。 } //bw.flush(); fw.close(); FileReader fr = new FileReader("e:/my.txt"); //通过Reader来创建字符缓冲区对象 BufferedReader br = new BufferedReader(fr); String strRead = null; while((strRead = br.readLine()) != null) {//判断是否为null,如果为null说明没有内容可读了。 System.out.println(strRead); } br.close(); fr.close(); } }
/** *【1】创建User类,包含以下属性name:String,age:int ,gender String,重写toString方法显示对象的信息 【2】使用BufferedWriter写入文件以“,”分隔 【3】使用BufferedReader读取信息并进行分割,还原成对象,调用 对象的toString方法输出对象的信息 */ package demo; public class User { private String name; private int age; private String gender; public User() { super(); // TODO Auto-generated constructor stub } public User(String name, int age, String gender) { super(); this.name = name; this.age = age; this.gender = gender; } 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; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } @Override public String toString() { return "User [name=" + name + ", age=" + age + ", gender=" + gender + "]"; } } ///////////////////////////////////////////////////////////////////////////////////// package demo; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class Demo08 { public static void main(String[] args) throws IOException { File file = new File("e:/user.txt"); if(file.exists()) { file.delete(); } file.createNewFile(); FileWriter fw = new FileWriter(file); BufferedWriter bw = new BufferedWriter(fw); User[] users = {new User("张三",18,"男"), new User("李四",22,"男"), new User("王五",16,"女"), new User("赵六",15,"男"), new User("秦阿琪",20,"女")}; for (User user : users) { bw.write(user.getName()+","+user.getAge()+","+user.getGender()); bw.newLine(); bw.flush(); } bw.close(); fw.close(); FileReader fr = new FileReader(file); BufferedReader br = new BufferedReader(fr); String read = null; while((read=br.readLine()) != null) { User user = new User(); String[] str = read.split(","); user.setName(str[0]); user.setAge(Integer.parseInt(str[1])); user.setGender(str[2]); System.out.println(user); } br.close(); fr.close(); } }
InputStreamReader 和 OutputStreamWriter
获得当前开发环境的字符编码方式
System.out.println(System.getProperty("file.encoding"));
涉及到的类:
读:FileReader (File file)
写:FileWriter(File file)
加入缓冲区的读:BufferedReader(Reader fr)
加入缓冲区的写:BufferedWriter(Writer bw)
当我们系统存储的编码格式和我们读写的格式不一致的时候,此时读写就会产生乱码。
构造方法:
Charset ===> 通过API可以知道,Charset.forName("编码名称");
//InputStreamReader package demo; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; public class Demo02 { public static void main(String[] args) throws IOException { File file = new File("e:/my.txt"); FileInputStream is = new FileInputStream(file); //通过InputStream创建对象,还可以指定编码格式。 InputStreamReader isr = new InputStreamReader(is,"UTF-8"); char[] ch = new char[1024]; int len = 0; while((len = isr.read(ch))!=-1) {//如果返回-1则没有内容可读了 System.out.println(new String(ch,0,len));//每次读ch个 } isr.close(); is.close(); } }
//OutputStreamWriter package demo; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; public class Demo03 { public static void main(String[] args) throws IOException { File file = new File("e:/my.txt"); FileOutputStream fos = new FileOutputStream(file); //通过OutputStream的对象来创建对象,还可以指定写入的编码格式。 OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8"); osw.write("我和你");//写入 osw.flush();//刷新缓冲区,从缓冲区写入程序 osw.close(); fos.close(); } }
Scanner的底层原理
package systemin; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.util.Scanner; public class Demo { public static void main(String[] args) throws IOException { //System.in的一个变量就是从键盘录入的数据源 // InputStream is = System.in; // InputStreamReader isr = new InputStreamReader(is); // BufferedReader br = new BufferedReader(isr); // BufferedWriter bw = new BufferedWriter(new FileWriter("d:/t.txt")); // String str = ""; // while(!"-1".equals(str = br.readLine())) { // bw.write(str); // bw.newLine(); // bw.flush(); // } Scanner sc = new Scanner(new File("d:/t.txt")); //System.out就是从文件写入到控制台 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); while(sc.hasNextLine()) { bw.write(sc.nextLine()); bw.newLine(); bw.flush(); } sc.close(); bw.close(); // br.close(); // System.out.println(str); //Scanner sc = new Scanner(str); } }
对象输入输出流: ObjectInputStream 和 ObjectOutputStream
写出对象的的时候,必须要实现Serializable接口,不然无法将对象写进磁盘上。出抛出这个异常: java.io.NotSerializableException
write.object();将一个对象写进磁盘,还有许多方法可以将对象的属性等写进出
write.flush();
read.object();将一个对象读出来,如果程序中没有该对象则会报错。
private static final long serialVersionUID = 1L;;声明版本号是为了后期修改对象的时候,读出来的数据会自动兼容。
package test; import java.io.Serializable; public class Dog implements Serializable{ /** * 声明版本号,如果出现成员变量的增加或者减少,读出来的数据会自动兼容 */ private static final long serialVersionUID = 1L; private String name; /** * transient 如果不需要将这个成员变量序列化到磁盘上,可以加这个关键字 */ private transient int age; public Dog() { super(); // TODO Auto-generated constructor stub } public Dog(String name, int age) { super(); this.name = name; this.age = age; } @Override public String toString() { return "Dog [name=" + name + ", 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; } } /////////////////////////////////////////////// package test; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; public class Demo { public static void main(String[] args) throws IOException { //对象的写入 File file = new File("e:/1.txt"); FileOutputStream fos = new FileOutputStream(file); ObjectOutputStream oos = new ObjectOutputStream(fos); Dog wangcai = new Dog("旺财",15); oos.writeObject(wangcai); oos.close(); //对象的读入 File file = new File("e:/1.txt"); FileInputStream fis = new FileInputStream(file); ObjectInputStream ois = new ObjectInputStream(fis); Object obj = ois.readObject();//会抛出ClassNotFoundException,用Object来接收 System.out.println(obj); ois.close(); } }
基本数据类型的流,输入和输出:DataInputStream 和DataOutputStream
package test; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; public class DataStream { public static void main(String[] args) throws IOException { //写 // File file = new File("e:/1.txt"); // FileOutputStream fos = new FileOutputStream(file); // DataOutputStream dos = new DataOutputStream(fos); // dos.writeInt(123); // dos.writeChar('a'); // dos.writeUTF("我和我的祖国"); // dos.close(); // fos.close(); //读 File file = new File("e:/1.txt"); FileInputStream fis = new FileInputStream(file); DataInputStream dis = new DataInputStream(fis); /** * 每次都读相同类型的数据,并且要根据写的顺序来读, * 不然读出来的就会不一样,或者直接报错 */ int n = dis.readInt(); System.out.println(n); char c = dis.readChar(); System.out.println(c); String str = dis.readUTF(); System.out.println(str); dis.close(); fis.close(); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· 字符编码:从基础到乱码解决
· Open-Sora 2.0 重磅开源!