java中文件读写操作(IO流)

39 阅读8分钟

IO流

I:input 输入(读取)把硬盘中的数据读取到内存中

O: output 输出(写入)把内存中的数据写入到硬盘中

io流分为数据的不同和方式的不同

字节流可以读取和写入任何文件类型

字符流就是单独的字符

读 写

字节流 InputStream OutputStream

字符流 Reader Write

image.png

File类

java中提供了对文件的一些操作的类

 package day0623;
 ​
 import java.io.File;
 import java.io.IOException;
 ​
 public class FileTest {
     public static void main(String[] args) throws IOException {
         /*
         *   File类,提供了对文件的一系列操作
         *   创建文件、文件夹
         *   删除文件
         * */
         //不同系统中文件的分隔符 win; linux:
         System.out.println(File.pathSeparator);
         //文件名中的分隔符
         System.out.println(File.separator);
         // \转义字符  \
         String path = "D:\user\a.txt;";
         //使用File类去创建
         String path2 = "D:"+File.separator+"user"
                 +File.separator+"a.txt"+File.pathSeparator;
         //相对路径:相对于当前文件(java项目中是相对于项目的根路径)
         //绝对路径:相对于盘符的
         //创建一个File对象
         //构造函数:可以是相对路径也可以是绝对路径,文件可以存在也可以不存在
         File f1 = new File("aaa");
         //打印文件的绝对路径
         System.out.println(f1.getAbsolutePath());
         //获取File对象构造函数中的路径
         // 文件名:文件路径、文件类型
         System.out.println(f1.getPath());
         // 判断文件是否存在
         System.out.println(f1.exists());
         // 如果不存在则创建文件
 //        if (!f1.exists()){
 //            f1.createNewFile();
 //        }
         //创建文件夹 mkdir()单级 mkdirs()多级
         String p1 = "aaa/bbb/ccc.txt";
         //以p1来创建File对象
         File f2 = new File(p1);
         //System.out.println(f2.mkdir());//false,创建失败
         System.out.println(f2.mkdirs());//true
         //f2.createNewFile();
         //删除文件
         // delete() 只会删除空的文件夹和单独的文件,不会递归删除
         System.out.println(f2.delete());
         //创建File对象
         File f3 = new File("aaa/bbb");
         System.out.println(f3.delete());
     }
 }
 ​

删除包含文件的文件夹:

 package day0623;
 ​
 import java.io.File;
 ​
 public class DeleteFile {
     public static void main(String[] args) {
         del(new File("aaa"));
     }
     public static void del(File file){
         if(!file.exists()) return;
         //参数有可能是文件也有可能是文件夹
         if (file.isDirectory()){
             //listFiles()获取文件夹的文件数组
             File[] files = file.listFiles();
             //循环数组,再次调用此方法
             for (File f:files){
                 del(f);
             }
         }
         file.delete();
     }
 }
 ​

FileInputStream 输入字节流

 package day0623;
 ​
 ​
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 ​
 public class FISTest {
     public static void main(String[] args) {
         //FileInputStream 输入字节流(读取)
         // 1.创建流 2.使用流 3.关闭流
         //构造函数支持两种:文件名的字符串或File对象
         //1.创建流
         FileInputStream fis = null;
         try {
             fis = new FileInputStream("a.txt");
             //2.使用流
             //read()读取文件中的字节,每次读取一个字节
             //System.out.println(fis.read());
             //创建一个字节数组用来接收内容
             byte[] b = new byte[1024];
             //System.out.println(Arrays.toString(b));
             int len = 0;//每次读取的字节数
             while((len= fis.read(b))!=-1){
                 //取出字节数组中的内容
                 // 从字节数组中读取出0-len位的内容
                 System.out.println(new String(b,0,len));
             }
             //3.关闭流
             fis.close();
         } catch (FileNotFoundException e) {
             e.printStackTrace();
         } catch (IOException e) {
             e.printStackTrace();
         }
     }
 }
 ​
 package day0623;
 ​
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.Arrays;
 ​
 public class FISTest2 {
     public static void main(String[] args) {
         //1.创建流
         FileInputStream fis = null;
         try {
             fis = new FileInputStream("a.txt");
             //2.使用流
             //fis.available() 获取fis对象的所有的字节数
             byte[] b = new byte[fis.available()];
             //读取内容至数组中
             fis.read(b);
             //3.关闭流
             fis.close();
             //System.out.println(Arrays.toString(b));
             System.out.println(new String(b));
         } catch (FileNotFoundException e) {
             e.printStackTrace();
         } catch (IOException e) {
             e.printStackTrace();
         }
     }
 }
 ​

BufferedInputStream 输入字节流的增强流

提供了缓冲区,减少系统的IO操作

 package day0623;
 ​
 import java.io.BufferedInputStream;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 ​
 public class BISTest {
     public static void main(String[] args) {
         //BufferedInputStream 字节输入增强流,提供了缓冲区、减少系统的IO操作
         //不使用的话每次都是操作系统去对文件进行操作、
         //使用后一次性先读取一部分,再从这个缓冲区读取
         //1.创建流
         FileInputStream fis = null;
         BufferedInputStream bis = null;
         try {
             fis = new FileInputStream("a.txt");
             bis = new BufferedInputStream(fis);
             //2.使用流
             byte[] b = new byte[1024];
             int len = 0;
             while ((len=bis.read(b))!=-1){
                 System.out.println(new String(b,0,len));
             }
             //3.关闭流
             bis.close();
         } catch (FileNotFoundException e) {
             e.printStackTrace();
         } catch (IOException e) {
             e.printStackTrace();
         }
     }
 }
 ​

FileOutputStream 输出字节流

 package day0623;
 ​
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 ​
 public class FOSTest {
     public static void main(String[] args) {
         File f = new File("b.txt");
 //        if (!f.exists()){
 //            try {
 //                f.createNewFile();
 //            } catch (IOException e) {
 //                e.printStackTrace();
 //            }
 //        }
         //1.创建流
         // 输出流会自动创建文件,但是只会创建文件不会创建目录
         FileOutputStream fos = null;
         //可以设置写入的内容是否是追加在后面
         try {
             fos = new FileOutputStream(f,true);
             //2.使用流
             fos.write(97);
             // 字符串转字节数组  getBytes()
             // 换行符 \r\n
             fos.write("abcdefg".getBytes());
             //3.关闭流
             fos.close();
         } catch (FileNotFoundException e) {
             e.printStackTrace();
         } catch (IOException e) {
             e.printStackTrace();
         }
 ​
     }
 }

复制文件:

 package day0623;
 ​
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 ​
 public class Copy {
     public static void main(String[] args) {
         //1.创建流
         FileInputStream fis = null;
         FileOutputStream fos = null;
         try {
             fis = new FileInputStream("鸣人.jpg");
             fos = new FileOutputStream("鸣人-副本.jpg");
             //2.使用流
             byte[] b = new byte[fis.available()];
             //读取内容
             fis.read(b);
             //写入内容
             fos.write(b);
             //3.关闭流
             fis.close();
             fos.close();
         } catch (FileNotFoundException e) {
             e.printStackTrace();
         } catch (IOException e) {
             e.printStackTrace();
         }
 ​
     }
 }
 ​

BufferedOutputStream 字节输出增强流

 package day0623;
 ​
 import java.io.BufferedOutputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 ​
 public class BOSTest {
     public static void main(String[] args) {
         //BufferedOutputStream字节输出增强流
         //1.创建流
         FileOutputStream fos = null;
         BufferedOutputStream bos = null;
         try {
             fos = new FileOutputStream("c.txt");
             bos = new BufferedOutputStream(fos);
             //2.使用流
             bos.write("abcdefg666".getBytes());
             //bos.flush();//将写入的内容更新至文件
             //3.关闭流
             bos.close();
         } catch (FileNotFoundException e) {
             e.printStackTrace();
         } catch (IOException e) {
             e.printStackTrace();
         }
 ​
     }
 }
 ​

FileReader 字符输入流

 package day0623;
 ​
 import java.io.FileNotFoundException;
 import java.io.FileReader;
 import java.io.IOException;
 ​
 public class FRTest {
     public static void main(String[] args) {
         //1.创建流
         FileReader fr = null;
         try {
             //构造函数可以是文件路径字符串也可以是File对象
             fr = new FileReader("fr.txt");
             //2.使用流
             //字符输入流每次读取一个字符
             //字符内容使用字节流读取打印内容时会有问题
             // GBK:中文编码格式 中文占2个字节
             // UTF-8:万国码 中文占3个字节
             char[] c = new char[1024];
             int len = 0;
             while((len=fr.read(c))!=-1){
                 System.out.print(new String(c,0,len));
             }
             //3.关闭流
         } catch (FileNotFoundException e) {
             e.printStackTrace();
         } catch (IOException e) {
             e.printStackTrace();
         }
     }
 }
 ​

BufferedReader 字符输入增强流

 package day0623;
 ​
 import java.io.BufferedReader;
 import java.io.FileNotFoundException;
 import java.io.FileReader;
 import java.io.IOException;
 ​
 public class BRTest {
     public static void main(String[] args) {
         //BufferedReader 字符输入增强流
         //1.创建流
         FileReader fr = null;
         BufferedReader br = null;
         try {
             fr = new FileReader("fr.txt");
             br = new BufferedReader(fr);
             String str = "";
             //2.使用流
             while ((str=br.readLine())!=null){
                 System.out.println(str);
             }
             //3.关闭流
             br.close();
         } catch (FileNotFoundException e) {
             e.printStackTrace();
         } catch (IOException e) {
             e.printStackTrace();
         }
     }
 }
 ​

InputStreamReader 字节通向字符的桥梁流

桥梁流是增加读取(写入的效率),底层操作字节效率更高,一般使用桥梁流也会封装增强流

 package day0623;
 ​
 import java.io.*;
 ​
 public class ISRTest {
     public static void main(String[] args) {
         //字节通向字符的桥梁
         //1.创建流
         FileInputStream fis = null;
         InputStreamReader isr = null;
         BufferedReader br = null;
         try {
             fis = new FileInputStream("fr.txt");
             isr = new InputStreamReader(fis);
             //2.使用流
             //不使用增强流
 //            char[] c = new char[1024];
 //            int len = 0;
 //            while ((len=isr.read(c))!=-1){
 //                System.out.println(new String(c,0,len));
 //            }
             //3.关闭流
             //isr.close();
             //使用增强流
             br = new BufferedReader(isr);
             String str = "";
             while ((str=br.readLine())!=null){
                 System.out.println(str);
             }
         } catch (FileNotFoundException e) {
             e.printStackTrace();
         } catch (IOException e) {
             e.printStackTrace();
         }
     }
 }
 ​

FileWrite 字符输出流

 package day0623;
 ​
 import java.io.FileWriter;
 import java.io.IOException;
 ​
 public class FWTest {
     public static void main(String[] args) {
         //FileWrite 字符输出流
         //1.创建流
         FileWriter fw = null;
         try {
             fw = new FileWriter("fw.txt",true);
             //2.使用流
             fw.write("你好");
             fw.write("HelloWorld");
             //3.关闭流,不关闭则不更新文件,除非手动调用 frush()
             fw.close();
         } catch (IOException e) {
             e.printStackTrace();
         }
     }
 }
 ​

BufferedWrite字符输出增强流

 package day0623;
 ​
 import java.io.BufferedWriter;
 import java.io.FileWriter;
 import java.io.IOException;
 ​
 public class BWTest {
     public static void main(String[] args) {
         //1.创建流
         FileWriter fw = null;
         BufferedWriter bw = null;
         try {
             fw = new FileWriter("fw.txt",false);
             bw = new BufferedWriter(fw);
             //2.使用流
             bw.write("晚上吃什么?");
             //3.关闭流
             bw.close();
         } catch (IOException e) {
             e.printStackTrace();
         }
     }
 }
 ​

OutputStreamWriter 字符到字节的桥梁流

 package day0623;
 ​
 import java.io.*;
 ​
 public class OSWTest {
     public static void main(String[] args) {
         //OutputStreamWrite 字符到字节的桥梁
         //1.创建流
         FileOutputStream fos = null;
         OutputStreamWriter osw = null;
         BufferedWriter bw = null;
         try {
             fos = new FileOutputStream("fw.txt");
             osw = new OutputStreamWriter(fos);
             bw = new BufferedWriter(osw);
             //2.使用流
             bw.write("哈哈哈");
             //3.关闭流
             bw.close();
         } catch (FileNotFoundException e) {
             e.printStackTrace();
         } catch (IOException e) {
             e.printStackTrace();
         }
     }
 }

序列化与反序列化

序列化

将java中的对象存储到文件中

 package day0623;
 ​
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.ObjectOutputStream;
 ​
 public class Xuliehua {
     public static void main(String[] args) {
         //序列化的类必须实现序列化接口java.io.Serializable
         //必须生成序列化ID,序列化id是一个标识,标识版本
         //1.创建需要序列化的对象
         String str = "你好";
         //2.创建流
         FileOutputStream fos = null;
         //创建序列化的流
         ObjectOutputStream oos = null;
         try {
             fos = new FileOutputStream("str.txt");
             oos = new ObjectOutputStream(fos);
             //3.使用流
             //将对象写入文件中,跟写字符串没区别,只是看不懂这个字符串
             oos.writeObject(str);
             //4.关闭流
             oos.close();
         } catch (FileNotFoundException e) {
             e.printStackTrace();
         } catch (IOException e) {
             e.printStackTrace();
         }
     }
 }

反序列化

将文件中的对象读取到内存中

 package day0623;
 ​
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 ​
 public class Fanxuliehua {
     public static void main(String[] args) {
         //1.创建流
         FileInputStream fis = null;
         ObjectInputStream ois = null;
         try {
             fis = new FileInputStream("str.txt");
             ois = new ObjectInputStream(fis);
             //2.使用流
             String str =(String) ois.readObject();
             System.out.println(str);
             //3.关闭流
             ois.close();
         } catch (FileNotFoundException e) {
             e.printStackTrace();
         } catch (IOException e) {
             e.printStackTrace();
         } catch (ClassNotFoundException e) {
             e.printStackTrace();
         }
     }
 }
 ​

登录注册操作

 package day0623;
 ​
 import java.io.*;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Scanner;
 ​
 public class LoginSystem {
     static Scanner sc = new Scanner(System.in);
     public static void main(String[] args) {
         //有一个存储了所有用户信息的对象
         List<User> list = null;
         //从文件中读取这个集合
         FileInputStream fis = null;
         ObjectInputStream ois = null;
         try {
             fis = new FileInputStream("user.txt");
             ois = new ObjectInputStream(fis);
             list = (List<User>) ois.readObject();
         } catch (FileNotFoundException e) {
             //文件不存在,list就初始化失败
             //e.printStackTrace();
             list = new ArrayList<>();
         }  catch (EOFException e){
             //读到了空文件的异常
             list = new ArrayList<>();
         }
         catch (ClassNotFoundException e) {
             e.printStackTrace();
         }
         catch (IOException e) {
             e.printStackTrace();
         }
         //list初始化完成
         int c = 0;//选择的数值
 ​
         User u = null;//表示当前登录的用户
         while (true){
             System.out.println("1.登录 2.注册 3.退出");
             c = sc.nextInt();
             if(c==1){
                 //登录
                u = login(list);
 //               if(u!=null){
 //                   //二级菜单
 //               }
             }else if (c==2){
                 //注册
                 register(list);
             }else {
                 //序列化list
                 exit(list);
                 //退出程序
                 System.exit(1);
             }
         }
     }
     public static User login(List<User> list){
         //登录
         //让用户输入账号密码,验证是否存在这个账号,
         // 并将获取的用户返回出去
         System.out.println("请输入账号:");
         String username = sc.next();
         System.out.println("请输入密码:");
         String password = sc.next();
         for (User u:list) {
             //循环集合,看是否有这个用户
             if (u.getUsername().equals(username)
             &&u.getPassword().equals(password)){
                 System.out.println("登录成功!");
                 return u;
             }
         }
         //没有这个用户
         System.out.println("账号或密码错误!");
         return null;
     }
     public static void register(List<User> list){
         //注册
         System.out.println("请输入账号:");
         String username = sc.next();
         //账号是否存在
         for (User u:list) {
             if (u.getUsername().equals(username)){
                 System.out.println("账户已存在!");
                 return;//结束方法
             }
         }
         System.out.println("请输入密码:");
         String password = sc.next();
         System.out.println("请输入昵称:");
         String nickname = sc.next();
         //创建user对象,添加进list中
         User user = new User(username,password,nickname);
         list.add(user);
     }
     public static void exit(List<User> list){
         //序列化
         FileOutputStream fos = null;
         ObjectOutputStream oos = null;
         try {
             oos = new ObjectOutputStream
                     (new FileOutputStream("user.txt"));
             oos.writeObject(list);
             oos.close();
         } catch (IOException e) {
             e.printStackTrace();
         }
     }
 }