Java文件

文件

File类,java.io.File,使用该类的构造函数就可以创建文件对象,将硬盘中的一个具体的文件以 Java 对象的形式来表示。

方法描述
public File(String pathname) 根据路径创建对象
public String getName() 获取文件名
public String getParent() 获取文件所在的目录
public File getParentFile() 获取文件所在目录对应的File对象
public String getPath() 获取文件路径
public boolean exists() 判断文件是否存在
public boolean isDirectory() 判断对象是否为目录
public boolean isFile() 判断对象是否为文件
public long length() 获取文件的大小
public boolean createNewFile() 根据当前对象创建新文件
public boolean delete() 删除对象
public boolean mkdir() 根据当前对象创建目录
public boolean renameTo(File file) 为已存在的对象重命名

IO流

Input 输入流(将外部文件读入到 Java 程序中)

Output 输出流(将 Java 程序中的数据输出到外部)

Java中的流有很多种不同的分类:

  • 按照方向分,可以分为输入流和输出流

  • 按照单位分,可以分为字节流和字符流(字节流是指每次处理的输出以字节为单位,字符流是指每次处理数据以字符为单位)

  • 按照功能分,可以分为节点流和处理流

字节流

按照方向分可以分为输入字节流InputStream和输出字节流OutputStream

InputStream常用方法:

方法描述
int read() 以字节为单位读取数据
int read(byte b[]) 将数据存入 byte 类型的数组中,返回数组中有效数据的长度
int read(byte b[],int off,int len) 将数据存入 byte 数组的指定区间内,返回数组长度
byte[] readAllBytes() 将所有数据存入 byte 数组并返回
int available() 返回当前数据流未读取的数据个数
void close() 关闭数据流
 @Test
 public void testInputStream() throws Exception{
     // 若file路径不存在不报错
     File file = new File("/Users/jarreet/Desktop/testInput.txt");
     if(file.exists()){
         InputStream is = new FileInputStream(file);
         // 使用下面这种方法穿创建输入流,若file路径不存在,会抛出异常
         // InputStram is = new FileInputStream("/Users/jarreet/Desktop/testInput.txt")
         int temp = 0;
         while((temp = is.read()) != -1){
             System.out.prinln("当前读取到的数据是" + temp + "当前未读取到的数据是" + is.avaliable());
        }
         is.close();
    }
 }

OutputStream常用方法:

方法描述
void write(int b) 以字节为单位输出数据
void write(byte b[]) 将byte数组中的数据输出
void write(byte b[],int off,int len) 将byte数组中指定区间的数据输出
void close() 关闭数据流
void flush() 将缓冲流中的数据同步到输出流中
 @Test
 public void testOutputStream() throws Exception{
  OutputStream os = new FileOutputStream("/Users/jarreet/Desktop/testOutput.txt");
     byte[] bytes = {105, 111, 999};
     os.write();
     os.close();
 }

字符流

字节流时单位时间内处理一个字节的数据(输入+输出)

字符流时单位时间内处理一个字符的数据(输入+输出)

按照方向分可以分为输入字符流 Reade r和输出字符流 Writer

Reader:

Reader是一个抽象类,继承了Readable接口.

Readable接口的作用:可以将数据以字符的形式读入到缓冲区

FileReader继承于InputStreamReader,InputStreamReader继承于Reader;InputStreamReader 的功能是将字节输入流转为字符输入流

InputStream(字节输入流)→ Reader(字符输入流)

 @Test
 public void testReader() throws Exception{
     // FileReader继承于InputStreamReader,InputStreamReader继承于Reader
     Reader reader = new FileReader("/Users/jarreet/Desktop/testReader.txt");
     
     int temp = 0;
     while((temp = reader.read()) != -1){
         Systemp.out.println(temp);
    }
     
     reader.close();
 }

字符与字节的转换关系:

  • 英文、数字、符号:1字节 = 1字符

  • 汉字:3字节 = 1字符

Writer:

Writer也是一个抽象类,继承了Appendable接口

Appendable接口的作用:可以将char类型的数据读入到数据缓冲区

FileWrite继承于OutputStreamWriter,OutputStreamWriter继承于Writer;OutputStreamWriter 的功能是将输出字节流转成输出字符流

 @Test
 public void testWriter() throws Exception{
     // FileWrite继承于OutputStreamWriter,OutputStreamWriter继承于Writer
     Writer writer = new FileWriter("/Users/jarreet/Desktop/testWriter.txt");
     
  writer.write("HelloWorld");
     writer.flush;
     
     writer.close();
 }

处理流

  1. 读文件

     @Test
     public void testInputStreamReader() throws Exception{
         // 基础管道
         InputStream is = new FileInputStream("/Users/jarreet/Desktop/testInputStreamReader.txt");
         // 处理流
         InputStreamReader isr = new InputStreamReader(is);
         char[] chars = new char[1024];
         int length = isr.read(chars);
         
         isr.close();
         
         String relust = new String(chars, 0, length);
         System.out.println(result);
     }
  2. 写文件

     @Test
     public void testOutputStreamWriter() throws Exception{
         String str = "你好 世界";
         // 基础管道
         OutputStream os= new FileOutputStream("/Users/jarreet/Desktop/testOutputStreamWriter.txt");
         // 处理流
         OutputStreamWriter osw = new OutputStreamWriter(os);
         
         writer.write(str);
         writer.flush();
         
         writer.close();
     }

缓冲流

无论是字节流还是字符流,使用的时候都会频繁访问硬盘,对硬盘是一种损伤,同时效率不高,如何解决?

可以使用缓冲流,缓冲流自带缓冲区,可以一次性从硬盘中读取部分数据存入缓冲区,再写入内存,这样就可以有效减少对硬盘的直接访问

缓冲流属于处理流,如何区分节点流和处理流?

  1. 节点流使用的时候可以直接对接到文件对象File

  2. 处理流使用的时候不可以直接对接到文件对象 File,必须要建立在字节流的基础上才能创建

缓冲流又可以分为字节缓冲流和字符缓冲流,按照方向再细分,又可以分为字节输入流缓冲流和字节输出缓冲流,以及字符输入缓冲流和字符输出缓冲流

  • 字节输入缓冲流

     @Test
     public void testBufferInputStream() throws Exception{
         // 创建节点流
         InputStream is = new FileInputStream("/Users/jarreet/Desktop/testBuffer.txt");
         // 创建缓冲流
         BufferedInputStream bis = new BufferedInputStream(is);
         
         byte[] bytes = new byte[1024];
         int length = bis.read(bytes);
         for(byte aByte : bytes){
             System.out.println(aByte);
        }
         bis.close();
         is.close();
     }
  • 字符输入缓冲流

    readLine 方法

     @Test
     public void testBufferReader() throws Exception{
         // 创建节点流
         Reader reader = new FileReader("/Users/jarreet/Desktop/testBuffer.txt");
         // 创建缓冲流
         BufferedReader br = new BufferedReader(reader)
         
      String str = null;
         int num = 0;
         System.out.println("===start===");
         while((str = br.readline()) != null){
      System.out.println(str);
             num++;
        }
         System.out.println(===end==="共读取了" + num + "次");
         br.close();
         reader.close();
     }
  • 字节输出缓冲流

    @Test
    public void testBufferOutputStream() throws Exception{
    // 创建节点流
    OutputStream os = new FileOutputStream("/Users/jarreet/Desktop/testBuffer.txt");
    // 创建缓冲流
    BufferedOutputStream bos = new BufferedOutputStream(os);

    String str = "君不见黄河之水天上来,奔流到海不复回。君不见高堂明镜悲白发,朝如青丝暮成雪。";
    byte[] bytes = str.getBytes();

    bos.write(bytes);
    bos.flush();

    bos.close();
    os.close();
    }
  • 字符输出缓冲流

    @Test
    public void testBufferWriter() throws Exception{
    // 创建节点流
    Writer writer = new FileWriter("/Users/jarreet/Desktop/testBuffer.txt");
    // 创建缓冲流
    BufferedWriter bw = new BufferedWriter(writer);

    String str = "君不见黄河之水天上来,奔流到海不复回。君不见高堂明镜悲白发,朝如青丝暮成雪。";

    bos.write(str);
    bos.flush();

    bw.close();
    writer.close();
    }

输入流没有 flush 方法,但不代表它没有缓冲流,输出流是有 flush 方法的,实际开发中在关闭输出缓冲流之前,需要调用 flush 方法

序列化和反序列化

  • 概念

    • 序列化就是将内存中的对象输出到硬盘文件中保存

    • 反序列化就是相反的操作,从文件中读取数据并还原成内存中的对象

  • 什么时候需要序列化?

    • 需要将内存的对象状态保存到文件中

    • 需要通过socket通信进行对象传输时

    • 我们将系统拆分成多个服务之后,服务之间传输对象,需要序列化

    序列化:

    1. 实体类需要实现序列化接口,Serializable

      @Data
      public class User implements Serializable {
      private Integer id;
      private String name;
      private Integer age;
      }
    2. 实体类对象进行序列化处理,通过数据流写入到文件中,ObjectOutputStream

      @Test
      public void testObject() throws Exception {
      User user = new User(1,"张三",22);
      OutputStream outputStream = new FileOutputStream("/Users/jarreet/Desktop/obj.txt");
      ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
      objectOutputStream.writeObject(user);
      objectOutputStream.flush();
      objectOutputStream.close();
      outputStream.close();
      }

    反序列化:

    @Test
    public void testObject1() throws Exception{
    InputStream inputStream = new FileInputStream("/Users/jarreet/Desktop/obj.txt");
    ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
    User user = (User) objectInputStream.readObject();
    System.out.println(user);
    objectInputStream.close();
    inputStream.close();
    }

IO流的应用

IO 流就是完成文件传输(上传文件:发朋友圈、换头像,文件下载:CSDN 下载源代码、文档)

    • 文本类型的数据(txt、word、Excel、MD)可以使用字符去读取(当然也可以用字节)

      @Test
      public void test() throws Exception{
      Reader reader = new FileReader("/Users/southwind/Desktop/test.txt");
      BufferedReader bufferedReader = new BufferedReader(reader);

      Writer writer = new FileWriter("/Users/southwind/myjava/test.txt");
      BufferedWriter bufferedWriter = new BufferedWriter(writer);

      String str = "";
      int num = 0;
      while ((str = bufferedReader.readLine())!=null){
      bufferedWriter.write(str);
      num++;
      }

      System.out.println("传输完毕,共读取了"+num+"次");
      bufferedWriter.flush();
      bufferedWriter.close();
      writer.close();
      bufferedReader.close();
      reader.close();
      }
    • 非文本类型的数据(图片、音频、视频)不能用字符去读取,只能用字节去读

      @Test
      public void test1() throws Exception{
      //1、通过输入流将文件读入到 Java
      InputStream inputStream = new FileInputStream("/Users/jarreet/Desktop/1.png");
      //2、通过输出流将文件从 Java 中写入到 myjava\
      OutputStream outputStream = new FileOutputStream("/Users/jarreet/myjava/1.png");
      int temp = 0;
      int num = 0;
      long start = System.currentTimeMillis();
      while((temp = inputStream.read())!=-1){
      num++;
      outputStream.write(temp);
      }
      long end = System.currentTimeMillis();
      System.out.println("传输完毕,共耗时"+(end-start));
      outputStream.flush();
      outputStream.close();
      inputStream.close();
      }


posted @ 2021-05-06 00:44  离渊灬  阅读(236)  评论(0)    收藏  举报