JavaIO

JAVA IO


文件

  • 什么是文件?

    文件是保存数据的地方,比如我们经常使用的word文档,txt文件,excel文件等都是文件。文件既可以保存一张图片,也可以保存视频,声音等

  • 文件流

    文件在程序中是以流的形式来操作的,

    流:数据在数据源和程序之间经历的路径

    输入流:数据从源到程序的路径

    输出流:数据从程序到数据源的路径

    在这里插入图片描述

常用的文件操作

  • 创建文件对象相关构造器和方法

    相关方法

    //new File(String pathname) //根据路径构建一个File对象
    //new File(File parent,String child) //根据父目录文件+子路径构建
    //new File(String parent,String child) //根据父目录+子路径构建
    //creatNewFile 创建新文件
    
    public class FileCreate {
        public static void main(String[] args) {
            FileCreate fileCreate = new FileCreate();
            fileCreate.create01();
            fileCreate.create02();
            fileCreate.creat03();
    
        }
    
        //方式1
        public void create01(){
            String filePath = "D:\\new1.txt";
            File file = new File(filePath);
            try {
                file.createNewFile();
                System.out.println("new1创建成功");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        //方式2
        public void create02(){
            File parentFile = new File("D:\\");
            String fileName = "new2.txt";
            File file = new File(parentFile, fileName);
            try {
                file.createNewFile();
                System.out.println("new2创建成功");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
    
        //方式3
        public void creat03(){
            String parentPath = "D:\\";
            String fileName = "new3.txt";
            File file = new File(parentPath, fileName);
            try {
                file.createNewFile();
                System.out.println("new3创建成功");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    
  • 目录的操作和文件删除

    mkdir创建一级目录、mkdirs创建多级目录、delete删除空目录或文件

    public class Directory {
        public static void main(String[] args) {
            m1();
            m2();
    
        }
    
        //判断文件是否存在,如果存在就删除
        public static  void m1(){
            String filePath = "D:\\new1.txt";
            File file = new File(filePath);
            if(file.exists()){
                if(file.delete()) System.out.println("删除成功");
                else System.out.println("删除失败");
            }else System.out.println("文件不存在");
        }
    
        //判断目录是否存在,如果存在就删除,没有就创建
        //Java编程中,目录也被当作一种文件
        public static  void m2(){
            String filePath = "D:\\demo\\a\\b";
            File file = new File(filePath);
            if(file.exists()){
                if(file.delete()) System.out.println("删除成功");
                else System.out.println("删除失败");
            }else{ System.out.println("目录不存在");
                if ( file.mkdirs()) System.out.println("目录创建成功");
                else System.out.println("目录创建失败");
            }}
    }
    

IO流

  • IO原理

    • I/O是Input/Output的缩写,I/O技术是非常实用的技术,可以用来处理数据传输。如读写文件,网络通讯等。
    • Java中,对于数据的输入输出操作以“流(stream)”的方式进行
  • IO流的分类

    • 按操作数据单位不同分为:字节流(8 bit),字符流(按字符)

    • 按数据流的流向不同分为:输入流,输出流

    • 按流的角色不同分为:节点流,处理流/包装流

      抽象基类字节流字符流
      输入流InputStreamReader
      输出流OutputStreamWriter

      java IO流共涉及40多个类,都是从以上4个抽象基类派生的

      由这四个基类派生出来的子类名称都是以其父类名作为子类名后缀

    • FileInputStream用法示例

      import java.io.FileInputStream;
      import java.io.FileNotFoundException;
      import java.io.IOException;
      
      public class FileInputStream_ {
      
          public static void main(String[] args) {
              readFile01();
              readFile02();
          }
      
          /**
           * 用read()方法一次读取一个字节
           */
          public static void readFile01(){
              String filePath = "D:\\new2.txt";
              int readData = 0;
              FileInputStream fileInputStream = null;
              try {
                  //创建FileInputStream对象用于读取字符
                  fileInputStream = new FileInputStream(filePath);
                  while((readData = fileInputStream.read()) != -1){
                      System.out.print((char)readData);
                  }
              } catch (IOException e) {
                  e.printStackTrace();
              }
              try {
                  fileInputStream.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      
          /**
           * 用read(byte[] b)方法一次读取多个字节
           */
          public static void readFile02(){
              String filePath = "D:\\new2.txt";
              byte[] bytes = new byte[8]; //eight bytes read once
              FileInputStream fileInputStream = null;
              int readLen = 0;
              //创建FileInputStream对象
              try {
                  fileInputStream = new FileInputStream(filePath);
                  while ((readLen = fileInputStream.read(bytes)) != -1){
                      System.out.print(new String(bytes,0,readLen));
                  }
              } catch (IOException e) {
                  e.printStackTrace();
              }
      
          }
      
      }
      
    • FileOutputStream用法示例

      import java.io.FileOutputStream;
      import java.io.IOException;
      
      public class FileOutputStream_ {
          public static void main(String[] args) {
              writeFile();
          }
      
          /**
           * 演示使用FileOutputStream 将数据写到文件里
           * 如果文件不存在,就创建文件
           */
          public static void writeFile(){
              String filePath = "D:\\new3.txt";
              FileOutputStream fileOutputStream1,fileOutputStream2 = null;
              try {
                  //1.new FileOutputStream(filePath)创建对象 写入当前内容,会覆盖原来内容
                  //2.new FileOutputStream(filePath,true)创建对象,写入当前内容会追加到原先内容的后面
                  fileOutputStream1 = new FileOutputStream(filePath);
                  fileOutputStream2 = new FileOutputStream(filePath,true);
                  //写入一个字节
                  fileOutputStream1.write('A');
                  //写入字符串
                  String str = "hello,world";
                  fileOutputStream1.write(str.getBytes());
                  fileOutputStream2.write(str.getBytes());
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      
      }
      

节点流和处理流

  1. 节点流可以从一个特定的数据源读写数据,如FileReader、FileWriter
  2. 处理流(包装流)是”连接“在已存在的流之上,为程序提供更强大的读写功能,也更加灵活,如BufferedReader、BufferedWriter
  3. 节点流是底层流/低级流,直接跟数据源相连接
  4. 处理流(包装流)包装节点流,既可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输入输出
  5. 处理流对节点流进行包装,使用了修饰器设计模式,不会直接与数据源相连
  • BufferedReader和BufferedWriter

演示BufferedReader

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.Reader;

public abstract class Reader_  {//抽象类

    public static void main(String[] args) throws Exception {
        String filePath = "d:\\new.txt";
        BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));

        //读取
        String len;
        //按行读取,返回null时文件读取完毕
        while ((len = bufferedReader.readLine()) != null) {
            System.out.println(len);

        }
        //关闭流,只需要关闭bufferedReader
        bufferedReader.close();
    }



}

演示BufferedInputStream和BufferedOutputStream

import java.io.*;

public class BufferedOutputStream_ {
    public static void main(String[] args) {
        copy();
    }

    public static void copy(){
        //设置源路径和目标路径
        String srcPath = "D:\\new.txt";
        String destPath = "D:\\new1.txt";
        BufferedOutputStream bufferedOutputStream = null;
        BufferedInputStream bufferedInputStream = null;
        try {
            //创建流
            bufferedInputStream = new BufferedInputStream(new FileInputStream(srcPath));
            bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(destPath));
            int readData;
            //读取和写入
            while((readData = bufferedInputStream.read()) != -1){
                bufferedOutputStream.write(readData);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(bufferedInputStream != null) bufferedInputStream.close();
                if(bufferedOutputStream != null) bufferedOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }
}

  • 对象流-ObjectInputStream和ObjectOutputStream

    • 序列化和反序列化

      • 序列化就是在保存数据时,保存数据的值和数据类型

      • 反序列化就是在恢复数据时,恢复数据类型和数据的值

      • 需要让某个类是可序列化的,该类必须实现以下两个接口之一

        1. Serializable (标记接口,没有方法,推荐)
        2. Externalizable

        ObjectOutputStream用法示例

      import java.io.FileOutputStream;
      import java.io.ObjectOutputStream;
      import java.io.Serializable;
      
      public class ObjectOutPutStream_ {
          public static void main(String[] args) throws Exception{
              //设置序列化后保存文件的路径
              String filePath = "D:\\data.dat";
              ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));
              //序列化数据到目标文件
              oos.writeDouble(1.1);
              oos.writeInt(26);
              oos.writeUTF("字符串");
              oos.writeObject(new Dog("小黄",3));  //保存一个自定义类的对象
              oos.close();
          }
      }
      
      
      //自定义Dog类
      class Dog implements Serializable{
          String name;
          int age;
      
          public Dog(String name, int age) {
              this.name = name;
              this.age = age;
          }
      }
      
      

​ ObjectInputStream用法示例

import java.io.FileInputStream;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.Serializable;
import com.liuxu.io.BufferedOutputStream_.* ;  //引入Dog类
public class ObjectInputStream_ {

    public static void main(String[] args) throws Exception{
        //读取 反序列化
        String filePath = "D:\\data.dat";

        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));

        //读取的顺序要和保存的数据一致,不然会出现异常
        System.out.println(ois.readDouble());
        System.out.println(ois.readInt());
        System.out.println(ois.readUTF());

        //首先要保证Dog类引入
        //如果希望调用Dog对象的方法,需要向下转型
        //需要将Dog类的定义放到可以引用的位置
        Object dog = ois.readObject();
        Dog dog1 = (Dog)dog;
        System.out.println(((Dog) dog).age);
        System.out.println(dog);

        ois.close();
    }

}

注意事项

  1. 序列化和反序列化时读写顺序要一致
  2. 需要被序列化和反序列化的对象需要实现Serializable接口
  3. 序列化的类中建议添加SerialVersionUID,来提高版本兼容性
  4. 序列化对象时默认会序列化所有属性,除了static和transient修饰的成员
  5. 一个类被序列化,则该类的子类也可以被序列化,序列化具备可继承性
  • 转换流InputStreamReader 和 OutStreamWriter

    Java默认为UTF-8编码,当文件的编码方式不是UTF-8时,读取时可能会出现乱码,这时就需要转换流来指定编码

InputStreamReader示例

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;

public class InputStreamReader_ {

    public static void main(String[] args) throws Exception{
        String filePath = "D:\\new.txt";
        //FileInputStream 转成 InputStreamReader,指定编码GBK
        InputStreamReader gbk = new InputStreamReader(new FileInputStream(filePath), "gbk");
        BufferedReader reader = new BufferedReader(gbk);

        //读取并输出
        String s = reader.readLine();
        System.out.println(s);

        reader.close();
    }

}

OutputStreamWriter示例

import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.FilterOutputStream;
import java.io.OutputStreamWriter;

public class OutPutStreamWriter_ {

    public static void main(String[] args) throws Exception{
        String filePath = "D:\\new.txt";

        OutputStreamWriter utf8 = new OutputStreamWriter(new FileOutputStream(filePath), "utf-8");

        utf8.write("以utf8编码写入");

        utf8.close();
    }

}

OutputStreamWriter示例

import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.FilterOutputStream;
import java.io.OutputStreamWriter;

public class OutPutStreamWriter_ {

    public static void main(String[] args) throws Exception{
        String filePath = "D:\\new.txt";

        OutputStreamWriter utf8 = new OutputStreamWriter(new FileOutputStream(filePath), "utf-8");

        utf8.write("以utf8编码写入");

        utf8.close();
    }

}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值