前言
Java通过IO流获取文件中的数据,并把数据持久化。
Java的IO流体系很庞大,也很灵活;
一、File类
我们想要在Java中读写文件,首先得有1个文件;
1个File类的对象代表1个文件或者1个文件夹,我们通过File类的对象,完成对文件/目录的创建和修改操作;
package IOStream; import java.io.File; public class TestFile { public static void main(String[] args) { try { File file = new File("student/zhanggen.txt"); //0.判断相关API //判断文件是否存在? System.out.println(file.exists()); //判断文件是否为绝对路径? System.out.println(file.isAbsolute()); //判断是否为目录? System.out.println(file.isDirectory()); //判断是否为文件? System.out.println(file.isFile()); //1.创建文件 // f.createNewFile(); //获取当前文件/目录的父级目录(对象) System.out.println(file.getParentFile()); //获取当前文件/目录的名称(字符串) System.out.println(file.getParent()); //2.创建文件夹 //创建文件夹:只能创建1级目录 file.mkdir(); //创建文件夹:创建多级目录 file.mkdirs(); //3.文件/目录重用名 file.renameTo(new File("newfile.txt")); //4.查看相关API //查看文件的大小 System.out.println(file.length()); //查看文件的名字 System.out.println(file.getName()); //5.文件/目录删除 //file.delete(); } catch (Exception e) { e.printStackTrace(); } } }
1.创建1个文件的完整过程
package IOStream; import java.io.File; public class TetsCreateFile { public static void main(String[] args) { File file = new File("java/file/test.txt"); //1.判断父级目录是否存在? File ParentDirectory = new File(file.getParentFile().getAbsolutePath()); if (!ParentDirectory.exists()) { ParentDirectory.mkdirs(); } //2.判断文件是否存在? if (!file.exists()) { try { //3.文件不存在则创建文件! file.createNewFile(); } catch (Exception e) { e.printStackTrace(); } } } }
二、IO流简介
对于程序设计语言而言,输入输出系统(Input/Output)是非常核心的功能。
程序需要从配置文件/数据库中获取数据来内存中处理,也需要把在内存中处理好的数据保存到文件/数据库中。
1.什么是IO
以程序为中心,我们从外部数据源(文件、数据库)中读取外部数据到内存称之为Input;读
以程序为中心,我们处理完内存中数据,持久化到硬盘或者数据称之为Output; 写
以上2个动作我们统称为IO,也就是Input和Output这2个单词的缩写。
2.输入出流流
IO流是输入流和输出流的统称;
输入流:程序通过输入流,把数据输入到内存,进行处理;
输出流:程序通过输出流,把数据输出到硬盘,进行持久化;
3.IO流的种类
在java中我们通过IO流获取和保存数据;
(1)根据IO流的方向,我们把IO流分为输入流和输出流;
(2)根据IO流中传输的数据,分为字节流和字符流;
(3)根据IO流的功能,分为字节流和处理流;
其中节点流就是直接连接到文件的IO流;
处理流是嵌套在其他IO流上,不直接连接文件;
传输字节流:InputStream/OutputStream
传输字符流:Reader/Writer
在Java中以上4类,是所有IO类的抽象父类;我们通过它们的子类完成文件内容的读和写;
三、节点流
使用字符流读(FileReader、FileWriter)取文件中的文字信息,
使用字节流(FileInputStream,FileOutputStream)读取非文本信息,例如图片、声音、视频、图片等二进制信息。
1.FileInputStream读文件
package IOStream; import java.io.File; import java.io.FileInputStream; public class TestFileInputStream01 { public static void main(String[] args) throws Exception { //1.逐一读取文件 FileInputStream fis = new FileInputStream("student/zhanggen.txt"); // 读取1个字节(8个位)的数据,正好是1个英文字母, // 想要阅读1个汉字就需要1次阅读4个字节 System.out.println((char) fis.read()); System.out.println((char) fis.read()); System.out.println((char) fis.read()); fis.close(); //2.设置字节数组作为缓存,读取文件; FileInputStream fis01 = new FileInputStream("student/zhanggen.txt"); byte[] byteArray = new byte[1024]; fis01.read(byteArray); //1个Char内存上存储的是Uicode 编码的数字, 1个字符串是由多个字符组成的Char[] //所以字节数组可以转成1个字符串; System.out.println(new String(byteArray)); fis01.close(); //3.循环读取+缓存 FileInputStream fis02 = new FileInputStream("student/zhanggen.txt"); byte[] bytesBuffer = new byte[1024]; int len = 0; while ((len = fis02.read(bytesBuffer)) != -1) { System.out.println(new String(bytesBuffer, 0, len)); } fis02.close(); } }
2.FileOutputStream写文件
package IOStream; import java.io.FileOutputStream; public class TestFileOutputStream02 { public static void main(String[] args) throws Exception { FileOutputStream fos = new FileOutputStream("student/zhanggen.txt"); //把字符串变成字节数组getBytes() fos.write("渣女最常用的手段:情绪“控制”,男人不要再被骗;".getBytes()); fos.flush(); fos.close(); } }
3.FileReader读文件
package IOStream; import java.io.File; import java.io.FileReader; public class TestFileReader03 { public static void main(String[] args) throws Exception { FileReader file01 = new FileReader("student/zhanggen.txt"); //1.以1个字符为单位进行读取 System.out.println((char) file01.read()); file01.close(); //2.一次性读取文件内容 FileReader file02 = new FileReader("student/zhanggen.txt"); //把文件内容全部放到1个字节数组中了 char[] charArray = new char[1024]; int count = file02.read(charArray); System.out.println(new String(charArray, 0, count)); file02.close(); //3.循环读取 FileReader file03 = new FileReader("student/zhanggen.txt"); int count01 = 0; char[] charArray01 = new char[1024]; //把文件内容全部放到1个字节数组中了 while ((count01 = file03.read(charArray01)) != -1) { System.out.println(new String(charArray01, 0, count01)); } file03.close(); } }
4.FileWriter写文件
package IOStream; import java.io.FileWriter; public class TestFileWriter04 { public static void main(String[] args) throws Exception { //append=ture开启追加写模式 FileWriter file01 = new FileWriter("student/zhanggen.txt", true); file01.write("您好时间简史\r\n"); file01.flush(); file01.close(); } }
5.copy和move文件
package IOStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; public class TestCopy { public static void main(String[] args) throws Exception { copy("student/胡一菲.jpg", "student/胡二飞.jpg"); } public static void copy(String soure, String des) throws Exception { FileInputStream fis = new FileInputStream(soure); FileOutputStream fos = new FileOutputStream(des); byte[] buffer = new byte[1024]; while ((fis.read(buffer)) != -1) { fos.write(buffer); } fos.flush(); fos.close(); fis.close(); } public static void move(String soure, String des) throws Exception { copy("student/ef.jpg", "student/new_ef.jpg"); File file = new File(soure); if (file.exists()) { file.delete(); } } }
四、处理流
处理流就是对节点流进行过滤和处理;
1.缓冲流
带有缓冲区的流就是缓冲流,BufferedReader可以像Python中的readLine()一样,一行一行地读取数据;
package IOStream.Buffer; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.FileReader; public class Test01 { public static void main(String[] args) throws Exception { //处理流嵌套在节点流上; // BufferedInputStream bis = new BufferedInputStream(new FileInputStream("student/zhanggen.txt")); //一行一行地读取内容 BufferedReader br = new BufferedReader(new FileReader("student/zhanggen.txt")); String line = ""; while ((line = br.readLine()) != null) { System.out.println(line); } br.close(); } }
2.转换流
电在传输的过程中传输的是高压电,高压电必须经过变电所进行降压(把高压电降低到220V)才能供居民使用;
转换流就是充当着变电所的功能;
Scanner sc=new Scanner(System.in);
我们可以使用InputStreamReader、OutputStreamWriter把字节流转换成字符流,但是不能把字符流转换成字节流;
InputStreamReader
package IOStream.convert; import java.io.*; public class Test01 { public static void main(String[] args) throws Exception { //把字节输入流 (System.out)转换成字符输入流 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); br.close(); //关闭了 System.out.println("111"); } }
OutputStreamWriter
package IOStream.convert; import java.io.BufferedWriter; import java.io.OutputStreamWriter; public class Tetst02 { public static void main(String[] args) throws Exception { //把字节输出流(System.out)转换成字符输出流 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); bw.write("您好,我是周润发!"); bw.flush(); // bw.close(); //注意:关闭了System.out,我们就无法打印了 System.out.println("久仰!"); } }
3.对象流
对象流可以把对象这种结构化的数据保存到文件中,还能从文件中加载对象到程序中使用;
package IOStream.Obj; import java.io.*; //Java中的类实现了Serializable接口,它的对象才能被序列化。 class Person implements Serializable { private int id; private String name; private int age; public Person(int id, String name, int age) { this.id = id; this.name = name; this.age = age; } public int getId() { return id; } public void setId(int id) { this.id = id; } 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 class TestObj { public static void main(String[] args) throws Exception { String fileName = "student/person.dat"; //序列化:把对象转换成字节 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(fileName)); Person p1 = new Person(1, "刘老根", 18); oos.writeObject(p1); oos.flush(); oos.close(); //反序列化:把字节转回对象 ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileName)); Object obj = ois.readObject(); Person p2 = (Person) obj; System.out.println(p1.getId()); System.out.println(p2.getName()); System.out.println(p2.getAge()); ois.close(); } }
五、练习
偷梁换柱,模拟Word文件的内容修改功能,把文件中内容李白替换成李太白;
package FileOption; import java.io.*; public class Word { public static void main(String[] args) throws Exception { replace("student/zhanggen.txt", "未来", "Future"); } public static void replace(String fileName, String oldString, String newString) throws Exception { File sourceFile = new File(fileName); String sourceFileName = sourceFile.getName(); String temFileName = String.format("%s/副本_%s", sourceFile.getParentFile().getAbsolutePath(), sourceFileName); File temFile = new File(temFileName); if (!temFile.exists()) { temFile.createNewFile(); } BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(sourceFile.getAbsoluteFile()))); BufferedWriter bw = new BufferedWriter(new FileWriter(temFile)); String line = ""; while ((line = br.readLine()) != null) { line = line.replace(oldString, newString); bw.write(line); bw.newLine();//另起一行 bw.flush(); } br.close(); bw.close(); sourceFile.delete(); //先删除源文件 temFile.renameTo(sourceFile);//再使用临时文件替换源文件,偷梁换柱! } }