JAVASE的IO流部分

一、IO流分类方式:

1. 按照流的方向进行分类:

以内存作为参照物,往内存中去,叫做输入(Input)。或者叫做读(Read)。从内存中出来,叫做输出(Output)。或者叫做写(Write)。

2. 按照读取数据方式不同进行分类:

  • 按照字节的方式读取数据,一次读取1个字节byte,等同于一次读取8个二进制位。这种流是万能的,什么类型的文件都可以读取。包括:文本文件,图片,声音文件,视频文件等…
  • 按照字符的方式读取数据的,一次读取一个字符,这种流是为了方便读取普通文本文件而存在的,这种流不能读取:图片、声音、视频等文件。只能读取纯文本文件,连word文件都无法读取。

假设文件file1.txt ,a中国bc张三fe

采用字节流的话是这样读的:
第一次读:一个字节,正好读到’a’
第二次读:一个字节,正好读到’中’字符的一半。
第三次读:一个字节,正好读到’中’字符的另外一半。

采用字符流的话是这样读的:
第一次读:'a’字符('a’字符在windows系统中占用1个字节。)
第二次读:'中’字符('中’字符在windows系统中占用2个字节。)

二、常用IO流及其方法

1、 四大家族流(abstract class)

  • 四大流
  • 字节输入流 java.io.InputStream
  • 字节输出流 java.io.OutputStream
  • 字符输入流 java.io.Reader
  • 字符输出流 java.io.Writer
    (ps:根据结尾区分,InputStreamReader是字符输入流)
  • 所有的流都实现了:java.io.Closeable接口,都是可关闭的,都有close()方法。流毕竟是一个管道,这个是内存和硬盘之间的通道,用完之后一定要关闭,不然会耗费(占用)很多资源。
  • 所有的输出流都实现了:java.io.Flushable接口,都是可刷新的,都有flush()方法。养成一个好习惯,输出流在最终输出之后,一定要记得flush()刷新一下。这个刷新表示将通道/管道当中剩余未输出的数据强行输出完(清空管道!)刷新的作用就是清空管道注意:如果没有flush()可能会导致丢失数据。

2、常用的流

  • 文件专属:
  • java.io.FileInputStream(掌握)
  • java.io.FileOutputStream(掌握)
  • java.io.FileReader
  • java.io.FileWriter
  • FileInputStream的常用方法:
  • read()方法:返回值是字节本身。
  • read(byte[]b)方法:一次最多读取b.length个字节。返回值是读到的字节数量。没有读到字节的话返回值-1。减少内存和硬盘的交互,提高程序执行的效率。
  • int available():返回还剩可以读的字节数
  • long skip(long n):跳过几个字节不读取
    范例:(如何读取及输出)
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
 * FileInputStream用byte数组接收最终版
 */

public class FileInputStreamTest04 {
    public static void main(String[] args) {
        FileInputStream  file = null;
        try {
            file = new FileInputStream("E:\\JavaSE\\temp\\temp.txt");
            //准备一个byte数组
            byte [] bytes = new byte[4];
            //准备一个变量用来接收读到的字节数
            int i = 0;
            while((i=file.read(bytes))!=-1){
                //把byte数组转换成字符串输出
                System.out.println(new String (bytes,0,i));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            if(file!=null){
                try {
                    file.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}
  • FileOutputStream的常用方法:
  • 构造方法

FileOutputStream(String name) :传入一个文件名,如果不存在会新建,如果存在会将其内容清空重新写入
FileOutputStream(String name, boolean append): 传入一个文件名和true,则从文件末尾处开始写
FileOutputStream(File file);

  • 方法摘要

write(byte [] b):
write(byte [] b ,int off,int length):

  • 转换流:(将字节流转换成字符流)
  • java.io.InputStreamReader
  • java.io.OutputStreamWriter

范例:

        FileInputStream file = new FileInputStream("some.txt");
        InputStreamReader in = new InputStreamReader(file);
        BufferedReader br = new BufferedReader(in);
  • 缓冲流专属:带有缓冲区的字符输入流,不需要定义byte数组或者char数组。
  • java.io.BufferedReader:

BufferedReader(Reader in):传进去的流称为节点流,外部流称为包装流
bufferedreader.readLine()方法:每次读一行(不包括换行)

范例:

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

public class BufferedReaderTest01 {
    public static void main(String[] args) throws Exception{
        FileReader file = new FileReader("some.txt");
        BufferedReader br = new BufferedReader(file);
        String s = null;
        while((s=br.readLine())!=null){
            System.out.println(s);
        }
        br.close();//关闭最外层即可

    }
}

  • java.io.BufferedWriter

  • java.io.BufferedInputStream

  • java.io.BufferedOutputStream

  • 数据流专属:

DataOutputStream写的文件,只能用DataInputStream去读,并且读和写的顺序要一致。

  • java.io.DataInputStream

  • java.io.DataOutputStream

  • 标准输出流:

  • java.io.PrintWriter

  • java.io.PrintStream(掌握)

System.out生成的是一个PrintStram类
标准输出流默认输出到控制台,可以改变指向,用setOut()方法
标准输出流不需要手动close()关闭

范例:

        //标准输出流不再指向控制台,指向"today"文件
        PrintStream ps =new PrintStream(new FileOutputStream("today"));
        System.setOut(ps);
  • 对象专属流:
  • java.io.ObjectInputStream(掌握)
  • java.io.ObjectOutputStream(掌握)
    对象的序列化和反序列化
    序列化和反序列化

Serialize:将JAVA对象存储到硬盘上,将JAVA对象保存下来。
DeSerialize:将硬盘上的数据重新恢复到内存上,恢复成JAVA对象。
参与序列化和反序列化的对象必须实现Serializable接口,这是个标志借口,里面代码什么都没有。JVM看到Seriazable接口后会自动生成一个序列化版本号,用来区分类。自动生成的序列号的缺点:一旦代码被修改,版本号也变了,运行错误。
建议实现Serializable接口后,也手动生成序列化版本号。private static final long serialVersionUID = 1L;
transient关键字:不参与序列化

public interface Serializable {
}
  • 序列化单个对象:
    创建ObjectOutputStream对象;创建需要序列化的对象(实现Serializable接口);调用writeObject()方法将该对象写入文件中。

  • 反序列化单个对象:
    创建ObjectInputStream对象;调用readObject()方法(返回值类型为Object);输出obj。

  • 序列化多个对象:
    创建ObjectOutputStream对象;创建一个List集合,泛型为要序列化的对象类型;创建多个对象并add()到List集合中;调用writeObject()方法将List集合写入文件。

public class ObjectOutputStreamTest {
    public static void main(String[] args) throws Exception{
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("Black"));
        //序列化多个对象
        List<Student> list = new ArrayList<>();
        Student st1 = new Student(1,"Emma" );
        Student st2 = new Student(2,"Rena");
        list.add(st1);
        list.add(st2);
        out.writeObject(list);
        out.flush();
        out.close();
    }
}

class Student implements Serializable {
    private int id;
    private String name;
    
    public Student(int id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
    
}
  • 反序列化多个对象:
    创建ObjectInputStream对象;调用readObject()方法(返回值类型为对象类型,向下转型);foreach循环输出对象。
public class ObjectInputStreamTest {
    public static void main(String[] args) throws Exception{
        //反序列化多个对象
        ObjectInputStream in= new ObjectInputStream(new FileInputStream("Black"));
        //向下转型
        List<Student> list = (List<Student>)in.readObject();
        for(Student ss :list){
            System.out.println(ss);
        }
        in.close();
    }
}

输出结果:

Student{id=1, name=‘Emma’}
Student{id=2, name=‘Rena’}

三、File类:

文件或者目录路径名

1、构造方法:

File(String pathname)

2、常用方法:

返回值类型方法名
booleanexists();
booleancreatNewFile:不存在时,以文件的形式创建
booleanmkdir:以目录的形式创建
booleanmkdirs:以目录的形式创建 (包括所有父目录)
StringgetParent();返回当前路径的父路径名字符串,如果没有,返回null
FilegetParentFile() ;返回当前路径的父路径名,如果没有,返回null
StringgetAbsolutePath();返回绝对路径名字符串
FileFile getAbsoluteFile();返回绝对路径名形式
SringgetName();返回当前路径表示的文件或目录的名称
booleanisDirectory();测试此抽象路径名表示的文件是否是一个目录。
booleanisFile();测试此抽象路径名表示的文件是否是一个标准文件
LonglastModified();返回文件的最后一次修改时间,返回值为从1970到修改时间的毫秒数
longlength();返回此抽象路径名表示的文件的大小
File[]listFiles();返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件

四、IO+Properties配置文件

以后经常改变的数据,可以单独写到一个文件中,使用程序动态读取。将来只需要修改这个文件的内容,java代码不需要改动,不需要重新编译,服务器也不需要重启。就可以拿到动态的信息。
类似于以上机制的这种文件被称为配置文件。

并且当配置文件中的内容格式是:
key1=value
key2=value 的时候,我们把这种配置文件叫做属性配置文件

Java规范中有要求:属性配置文件建议以.properties结尾,但这不是必须的。其中Properties是专门存放属性配置文件内容的一个类。

public class IOPropertiesTest {
    public static void main(String[] args) throws Exception {
        //新建一个输入流对象
        FileReader Re = new FileReader("exercise04\\user.properties");
        //新建一个Map集合
        Properties  pro = new Properties();
        //调用Properties的load方法将文件的数据加载到Map集合中
        pro.load(Re);
        //通过key获取value
        System.out.println(pro.getProperty("password"));
    }
}

属性配置文件的key重复的话,value会自动覆盖

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值