javaIO流

文件

概念

文件就是保存数据的地方,万物皆文件。

文件流

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

| [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NyEVGTRb-1648566722944)(E:\qq文件\image\java进阶\文件流.jpg)] || ---------------------------------------------- |

流: 数据在数据源(文件)和程序(内存)之间经历的路径

输入流: 数据从数据源(文件)到程序(内存)的路径

输出流:数据从程序(内存)到数据源(文件)的路径

常用文件操作

创建文件

//创建文件对象相关构造器和方法
new File(String pathname)//根据路径构建一个File对象
new File(File parent,String child)//根据父目录文件+子路径构建
new File(String parent,String child) //根据父目录+子路径构建
 createNewFile() //创建新文件
  /**
    * 3.new File(String parent,String child)
    * 要求两个字符串要符合文件名字的类型不然汇报创建失败
  * */

获取文件相关信息

getName()获取文件名称
getAbsolutePath()获取文件的绝对路径
getParent()返回父目录文件路径
exists()文件是否存在
length()文件的大小(字符返回)
isFile()是不是文件
isDirectory()是不是文件夹
delete()删除文件

目录操作

在java编程中,目录也是一种文件处理方式。

  1. 先判断是否存在
  2. 在进行添加或者删除操作
目录创建
mkdir()创建一级目录
mkdirs()创建多级目录

IO原理以及流的分类

IO原理

  1. I/O是Input /Output的缩写 ,IO技术是非常实用的技术,用于数据的处理。如写文件,读文件
  2. java程序中,对于数据的输入输出操作以”流“的方式进行
  3. java.io包下提供了各种”流“的类和接口,用于获取不同类型的数据,并通过方法输入输出数据。

| [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4v9SiNhu-1648566722946)(E:\qq文件\image\java进阶\javaIo流原理.jpg)] || ---------------------------------------------------------- |

流的分类

  1. 按操作数据单位不同分为:字节流(8 bit)二进制文件,字符流(按字符)
字节流用于处理二进制文件:视频,声音,word文件,
字符流文本文件
  1. 按数据流的流向不同分为:输入流,输出流。
  2. 按流的角色的不同分为:节点流,处理流/包装流
抽象基类字节流字符流
输入流InputStreamReader
输出流OutputStreamWriter

节点流和处理流(重点)

节点流可以从一个特定的数据源读取数据,如FileReader,FileWriter

| [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Kw4JPKYL-1648566722948)(E:\qq文件\image\java进阶\节点流.jpg)] || ---------------------------------------------- |

处理流也叫包装流,是连接已存在的流之上,微程序提供更强大的读写功能如,BUfferedReader,BufferedWriter

| [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0c0L5VmQ-1648566722949)(E:\qq文件\image\java进阶\处理流.jpg)] || ---------------------------------------------- |

两个区别

节点流是一种底层流,直接跟数据源相接

处理流报装节点流,既可以下厨不同节点流的实现差异,也可以更加方便

的方法来完成输入输出

处理流对节点进行包装,使用了修饰器设计模式,不会直接与数据源相连**(模拟修饰器设计模式)**

修饰器设计模式模拟

//使用java中继承和动态绑定的机制,将一些处理数据源的节点流方式是成一个基类,或者抽象类,然后用一个类重写构造器,传入该类,就可以把很多类包装到一起
abstract class reader_ {
    public  abstract void  readFile();

    public abstract void readString();

}

class bufferReader { //包装好的可使用的
    private  reader_ reader;

    public bufferReader(reader_ reader) {
        this.reader = reader;
    }
}

  class  Stringreader extends  reader_{

    @Override
    public void readFile() {

    }

    @Override
    public void readString() {

    }
}

class  Filereader extends  reader_ {

    @Override
    public void readFile() {

    }

    @Override
    public void readString() {

    }
}

**字符处理流-**BUfferedReader,BufferedWriter

处理文本文件有很大优势。(字符)

**字节处理流-**BufferedinputStream和BufferedOutputStream

处理二进制文件【声音,视频,doc,pdf】(字节)

实列

 @Test
    public void bufferreader() {

        String filepath = "D:\\ajava.txt";

        try {
            BufferedReader bufferedReader = new BufferedReader(new FileReader(filepath));
            String line;
            //默认读取的文件是以UTF-8这种编码方式进行读取的
            while ((line = bufferedReader.readLine()) != null) {
                System.out.println(line);
            }
            bufferedReader.close();

        } catch (IOException e) {
            e.printStackTrace();
        }

    }


    @Test
    public void bufferWriter() {


        String filepath = "D:\\a.txt";

        try {
            BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filepath));
            String str = "你好韩顺平";
            bufferedWriter.write(str);

            bufferedWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
        }


    }

对象处理流-

ObjectInputStream和ObjectOutputStream

处理数据不是保存值,而是将数据的值和数据类型都进行保存到文件中,这样处理方便文件恢复,同时可以做到基本数据或者对象数据的序列化和反序列化

序列化和反序列化

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

  2. 反序列化就是在回复数据的时候,可以恢复数据的值和数据类型

  3. 需要让某个对象支持序列化机制,则必须让其类时可序列化的,为了让某个类时可序列化的。该类必须实现如下两个接口之一

    Serializable//这是一个标记接口,没有方法

    Externalizable//该接口有方法需要实现,因此我们一般实现上面的

ObjectInputStream和ObjectOutputStream 提供了对基本类型或者对象类型的序列化和反序列化的方法

示例

 @Test
    public void ObjectoutputStream() {
        String filepath = "D:\\ajava.dat";
        try {
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filepath, true));

            //序列化数据到 D:\ajava.dat
            oos.writeInt(100);  //int -> integer
            oos.writeBoolean(true);
            oos.writeChar('a');
            oos.writeUTF("韩顺平, 教育");
            oos.writeObject(new Dog("小孩", 15));
            Dog dog3 = new Dog("小组", 13);
            oos.writeObject(dog3);

            oos.close();
            System.out.println("数据序列化完毕");

        } catch (IOException e) {
            e.printStackTrace();
        }


    }


    @Test
    public void ObjectinputStream() {
        String filepath = "D:\\ajava.dat";
        try {
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filepath));

            System.out.println(ois.readInt());
            System.out.println(ois.readBoolean());
            System.out.println(ois.readChar());
            System.out.println(ois.readUTF());
            Object o = ois.readObject();
            System.out.println("运行类型:" + o.getClass());
            System.out.println(o);
            ois.close();

            //反序列化:读取的顺序要一致,否则会有异常

            ois.close();
            System.out.println("数据反序列化完毕");

        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }


    }


}

class Dog implements Serializable {

    //提高序列化 的兼容性,就是他不会因为你的类添加了一个属性,就是一个陌生的类
    private  static final long serialVersionUID = 1L;
    private String name;
    int age;

    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

对象处理流的细节

  1. 读写顺序一致
  2. 要求实现序列化或反序列化对象,需要实现Serializable
  3. 序列化的类中建议添加SerializableUID,为了提高版本的兼容性
  4. 序列化对象时,默认将里边所有属性进行序列化,但除了static或transient修饰的成员
  5. 序列化对象时,要求里面属性的类型也需要实现序列化接口
  6. 序列化具备继承性,也就是如果某类已经实现了序列化,则它的所有子类也已经默认实现了序列化

标准输入输出流

类型默认设备
System.in标准输入InputStream键盘
System.out标准输出PrintStream显示器
    @Test
    public void system() {
        //System.in
        //public final static InputStream in = null; 编译类型时InputStream
        //运行类型时BufferedInputStream
        System.out.println(System.in.getClass());

        //System.out
        //    public final static PrintStream out = null;; 编译类型时PrintStream
        //运行类型时 PrintStream 
        System.out.println(System.out.getClass());
    }

转换流

就是将字节流转换成字符流。

作用: 字节读取的时候默认的编码格式是UTF-8,如果为了防止出现文件乱码等现象,可以使用 转换流进行读写操作,该流中可以规定文件读取的编码格式并转换成对应的字符流

InputStreamReader 和 OutputStreamWriter

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dpujY11t-1648566722951)(E:\qq文件\image\java进阶\inputStreamReader.jpg)]
  1. InputStreamReader:Reader的子类,可以将InputStream(字节流)包装成Reader(字符流)
  2. OutputStreamWriter:Writer的子类,实现将OutputStream(字节流)包装成Writer(字符流)
  3. 当处理纯文本数据时,如果使用字符流效率更高,并且可以有效解决中文,所以建议将字节流转换成字符流

使用操作:

//1.把FileInputStream 转成InputStreamReader
 InputStreamReader gbk = new InputStreamReader(new FileInputStream(ser), "UTF-8");//2. 指定编码 

    

 
//3.把InputStreamReader 传入 BufferedReader  :将转换流转换成字符流    
     BufferedReader bufferedReader = new BufferedReader(gbk);

打印流

打印流只有输出流 没有输入流

PrintStream和 PrintWriter(字节流)

    /**
     * 演示PrintStream_ (字节打印流)
     */
    @Test
    public void PrintStream_() throws FileNotFoundException {

        //System.out;底层就是PrintStream,所以可以直接赋值
     PrintStream out = System.out;
     //在默认情况下,PrintStream 输出的位置就是标准输出:显示器
     out.println("你好");
     //我们可以修改打印输出的位置/设备
        System.setOut(new PrintStream("e:\\a.txt"));//设置输出的路径
        System.out.println("你好");//该句话就不会打印在显示器,而是编程上边设置的输出路径


    }


    /**
     * 演示PrintWriter_ (字节打印流)
     */
    @Test
    public void PrintWriter_ () throws IOException {

        PrintWriter printWriter = new PrintWriter(new FileWriter("D:\\a.txt"));
        printWriter.write("你好");
        printWriter.checkError();//如果不关闭就不会把数据输出
    }

字节流

InputStream(字节)

常用子类

1.FilelnputStream:文件输入流
2.BufferedInputStream:缓冲字节输入流

3.ObjectlnputStream:对象字节输入流

FilelnputStream的使用

  1. 创建

    FileInputstream fileInputStream = null;
    
  2. 打开文件,读取(流和文件进行绑定)

    //从该输入流读取一个字节的数据。如果没有输入可用,此方法将阻止。/如何返回-1,表示读取完毕
    //read():一个字节一个字节的读取
    
        while ((readData = fileInputstream.read()) != -1) {
           System.out.println((char)readData);//转成char显示
        }
    //read(byte[] b):按照byte最大的数组进行读取,不在一个一个
    
    //fileInputstream.read(buff)的返回值是实际读取的字节数,如果读完返回-1
    int readLength
    byte[] buff = new byte[127]
        while ((readLength = fileInputstream.read(buff)) != -1) {
           System.out.println(new         									String(buff,0,readLength));//转成char显示            
        }
    
  3. 释放

fileInputstream.close();

OutputStream

FileOutputStream的使用和FilelnputStream使用方式类似,不同的是一个输出一个输入

字节输出流

  1. 单字节输出 fileoutputstream.write()
  2. char数组输出 fileoutputstream.write(byte[] str )

FileOutputStream在进行输出到文件中时,如果该文件不存在就会创建该文件。

字符流

Reader(字符) Writer(字符)

字符流的基类。

FileReader和FileWriter

FileWriter常用方法
1) new FileWriter(File/String)覆盖模式,相当于流的指针在首端
new FileWriter(File/String,true):追加模式,相当于流的指针在尾端
write(int)写入单个字符
write(char)写入指定数组
write(char0.off,len)写入指定数组的指定部分
write (string)写入整个字符串
write(string,off,len)写入字符串的指定部分

注意

FileWriter使用后,必须关闭或者刷新flush,否则写入不到指定文件

Properties类

多用于配置文件,格式: 键=值,默认是String类型

常用方法

load :加载配置文件的键值对到Properties对象

list:将数据显示到指定设备

getProperties(key):根据键获取到值

setProperties(key,value):设置键值到Properties对象

store:将Properties中的键值对存储到配置文件中,保存配置信息,如果含有中文,就存储Unicode码

实列

 @Test
    public void Properties_() throws IOException {
        String filepath = "src\\Mysql.properties";
//以下是传统方法,对配置文件的处理方式
/*        BufferedReader bufferedReader = new BufferedReader(new FileReader(filepath));
        String str;
        //为空则读取完成
        while ((str = bufferedReader.readLine()) != null) {
            System.out.println(str);

        }
        bufferedReader.close();*/

        Properties properties = new Properties();
        //加载
        properties.load(new FileReader(filepath));
        //配置显示设备
        properties.list(System.out);

        //如果没有k-v就是添加
        //如果有就是修改
        properties.setProperty("user","zzx");
        //保存修改内容到配置文件
        properties.store(new FileWriter(filepath,false),null);
        properties.clear();

        //如果要求指定的得到某个对应的数据,就可以用Properties

    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值