Java IO最详解

字节流

字节流抽象基类

● InputStream: 这个抽象类是表示字节输入流的所有类的超类
● OutputStream: 这个抽象类是示字节输出流的所有类的超类
● 子类名特点: 子类名称都是以其父类名作为子类名的后缀

FileOutputStream: 文件输出流用于将数据写入File

● FileOutputStream(String name): 创建文件输出流以指定的名称写入文件
使用字节输出流写数据的步骤:
● 创建字节输出流对象(调用系统功能创建 了文件,创建字节输出流对象,让 字节输出流对象指向文件)
● 调用字节输出流对象的写数据方法
● 释放资源 (关闭此文件输出流并释放 与此流相关联的任何系统资源)

OutputStream f = new FileOutputStream(“C:/java/hello”)
import java.io.FileOutputStream;
import java.io.IOException;

public class FileOutputStreamDemo01 {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("myByteStream\\fos.txt");
        //byte[] bys={97,98,99,100,101};
        byte[] bys = "abcde".getBytes();
        fos.write(bys,1,3);
        fos.close();
    }
}

在这里插入图片描述

字节流读数据

FileInputStream: 文件输入流用于读取数据
● 该流用于从文件读取数据,它的对象可以用关键字 new 来创建。

● 有多种构造方法可用来创建对象。

● 可以使用字符串类型的文件名来创建一个输入流对象来读取文件:

InputStream f = new FileInputStream(“C:/java/hello”);

字节流写数据的两个小问题

字节流写数据换行问题:

● 写完数据后, 加换行符
windows:\r\n
linux:\n
mac:\r
字节流写数据实现追加写入:
public FileOutputStream(String name, boolean append)
● 创建文件输出流以指定的名称写入文件。 如果第二个参数为true,则字节将写入文件的末尾而不是开头

字节缓冲流

字节缓冲流:
● BufferOutputStream:该类实现缓冲输出流。通过设置这样的输出流, 应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用
● BufferedInputStream:创建BufferedInputStream将创建一 个内部缓冲区数组。 当从流中读取或跳过字节时, 内部缓冲区将根据需要从所包含的输入流中重新填充,一次很多字节。
构造方法:
● 字节缓冲输出流: BufferedOutputStream(OutputStream out)
● 字节缓冲输入流: BufferedInputStream(InputStream in)

为什么构造方法需要的是字节流,而不是具体的文件或者路径呢?

● 字节缓冲流仅仅提供缓冲区, 而真正的读写数据还得依靠基本的字节流对象进行操作

package com.itheima_02;

import java.io.*;

public class BufferStreamDemo {
    public static void main(String[] args) throws IOException {
        //FileOutputStream fos  =new FileOutputStream("myByteStream\\bos.txt");
        /*BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("myByteStream\\bos.txt"));
        bos.write("hello\r\n".getBytes());
        bos.write("world\r\n".getBytes());
        bos.close();*/
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("myByteStream\\bos.txt"));
        //int by;
        //while((by = bis.read())!=-1) {
          //  System.out.print((char)by);
        //}
        byte[] bys = new byte[1024];
        int len;
        while((len = bis.read(bys))!=-1) {
            System.out.println(new String(bys,0,len));
        }
        bis.close();
    }
}

用字节流复制视频文件代码样例

import java.io.*;

public class CopyAviDemo {
    public static void main(String[] args) throws IOException {
        long StartTime = System.currentTimeMillis();
        method4();

        long endTime = System.currentTimeMillis();
        System.out.println("共耗时:" + (endTime - StartTime) +"毫秒");
    }
    //基本字节流一次读写一个字节
    //共耗时:97687毫秒
    public static void method1() throws IOException {
        FileInputStream fis = new FileInputStream("E:\\itcase\\01.mp4");
        FileOutputStream fos = new FileOutputStream("myByteStream\\01.mp4");
        int by;
        while((by = fis.read())!=-1) {
            fos.write(by);
        }
        fos.close();
        fis.close();
    }
    //基本字节流一次读写一个字节数组
    //共耗时:120毫秒
    public static void method2() throws IOException {
        FileInputStream fis  = new FileInputStream("E:\\itcase\\01.mp4");
        FileOutputStream fos = new FileOutputStream("myByteStream\\01.mp4");
        byte[] bys = new byte[1024];
        int len;
        while((len = fis.read(bys))!=-1) {
            fos.write(bys,0,len);
        }
        fos.close();
        fis.close();
    }
    //字节缓冲流一次读一个字节
    //共耗时:300毫秒
    public static void method3() throws IOException {
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("E:\\itcase\\01.mp4"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("myByteStream\\01.mp4"));
        int by;
        while((by = bis.read())!=-1) {
            bos.write(by);
        }
        bos.close();
        bis.close();
    }
    //字节缓冲流一次读写一个字节数组
    //共耗时:30毫秒
    public static void method4() throws IOException {
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("E:\\itcase\\01.mp4"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("myByteStream\\01.mp4"));
        byte[] bys = new byte[1024];
        int len;
        while((len = bis.read(bys)) != -1) {
            bos.write(bys,0,len);
        }
        bos.close();
        bis.close();
    }
}

一个汉字存储:
● GBK编码一个汉字占用2个字节。
● UTF-8编码一个汉字占用3个字节。

字符流

字符流 = 字节流 + 编码表;
字符流抽象基类
● Reader: 字符输入流的抽象类
● Write:字符输出流抽象类
字符流中和编码解码问题相关的两个类:

InputStreamReader :是从字节流到字符流的桥接器:它使用指定的charset读取字节并将其解码为字符。 它使用的字符集可以通过名称指定,也可以明确指定,或者可以接受平台的默认字符集。

OutputStreamWriter:是从字符流到字节流的桥接器:使用指定的charset将写入其中的字符编码为字节。 它使用的字符集可以通过名称指定,也可以明确指定,或者可以接受平台的默认字符集。

字符缓冲流

BufferedWriter:
将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的效写入,可以指定缓冲区大小,或者可以接受默认大小。默认值足够大,可用于大多数用途。
BufferedReader:
从字符输入流读取文本,缓中字符,以提供字符,数组和行的高效读取,可以指定缓冲区大小,或者可以使用默认大小。默认值足够大,可用于大多数用途。
构造方法:
BufferedWriter(Writer out)
BufferedReader(Reader in)

import java.io.*;

public class BufferedStreamDemo {
    public static void main(String[] args) throws IOException {
//        FileWriter fw = new FileWriter("myCharStream\\bw.txt");
//        BufferedWriter bw = new BufferedWriter(fw);
//        bw.write("hello\r\n");
//        bw.write("world");
//        bw.close();
        BufferedReader br = new BufferedReader(new FileReader("myCharStream\\bw.txt"));
        //一次读一个字符数据
//        int ch;
//        while((ch = br.read())!=-1) {
//            System.out.print((char)ch);
//        }
        //一次读一个字符组数据
        char[] chs = new char[1024];
        int len;
        while((len = br.read(chs))!=-1) {
            System.out.println(new String(chs,0,len));
        }
        br.close();

    }
}

字符缓冲流特有功能复制文件:

public class CopyJavaDemo01 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("myCharStream\\ConversionStreamDemo.java"));
        BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream\\Copy.java"));
        String line;
        while((line = br.readLine())!=null) {
            bw.write(line);
            bw.newLine();
            bw.flush();

        }
        bw.close();
        br.close();
    }
}

总结:
在这里插入图片描述
在这里插入图片描述

properties类

Properties类表示一组持久的属性。 Properties可以保存到流中或从流中加载。 属性列表中的每个键及其对应的值都是一个字符串。
常用方法:
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;

public class Demo02 {
    public static void main(String[] args)throws IOException {
        //show02();
        show03();
    }
    private static void show02() throws IOException{
        //创建Properties集合对象,添加数据
        Properties prop = new Properties();
        prop.setProperty("张一山","20");
        prop.setProperty("杨紫","20");
        prop.setProperty("迪丽热巴","21");
        //创建字节输出流/字符输出对象,构造方法中绑定输出的目的地

        FileWriter fw = new FileWriter("myCharStream\\prop.txt");
       //使用Properties中的方法store,把集合中的数据写入硬盘
        prop.store(fw,"save data");
        fw.close();
    }
    private static void show03() throws IOException {
        Properties prop = new Properties();
        //使用Properties集合对象中的方法load读取键值对的文件
        prop.load(new FileReader("myCharStream\\prop.txt"));
        //遍历Properties集合
        Set<String> set = prop.stringPropertyNames();
        for(String key : set) {
            String value = prop.getProperty(key);
            System.out.println(key + "=" +value);
        }

    }
}

序列化和反序列化*

对象序列化和反序列化:

● 就是将对象保存到磁盘中,或者在网络中传输对象;
● 这种机制就是使用一个字节序列表示个对象, 该字节序列包含:对象的类型、对象的数据和对象中存储的属性等信息;
● 字节序列写到文件之后,相当于文件中持久保存了一个对象的信息;

反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化要实现序列化和反序列化就要使用对象序列化流和对象反序列化流:

● 对象序列化流: ObjectOutputStream
● 对象反序列化流: ObjectInputStream
对象序列化流
对象序列化流: ObjectOutputStream
将Java对象的原始数据类型和图形写入OutputStream。可以使用ObjectInputStream读取 (重构)对象。可以通过使用流的文件来实现对象的持久存储。如果流是网络套接字流,则可以在另个主机上或另一个进程中重构对象
注意:
一个对象要想被序列化, 该对象所属的类必须必须实现Serializable 接口
Serializable是一个标记接口,实现该接口,不需要重写任何方法。
用对象序列化流序列化了一个对象后,如果修改了对象所属的类文件,需要给对象所属的类加一个值:private static final long serialVersionUID = 42L(举例 : 42L)
transient 关键字
被transient修饰的成员变量不参与序列化过程。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值