首页 > 其他 > 详细

I/O流

时间:2021-05-22 23:23:28      阅读:24      评论:0      收藏:0      [点我收藏+]

在Java中,数据的输入/输出操作以“流”的方式进行

 

字节流:以字节为单位获取数据(命名以Stream结尾的一般是字节流)
字符流:以字符为单位获取数据(以Reader/Writer结尾的一般是字符流)

节点流:可以直接从数据源或目的地读写数据
处理流:不直接连接到数据源或目的地,是处理流的流,处理流也叫包装流
FilterInputStream和FilterOutputStream是所有包装流的父类

 

节点流的父类:InputStream和OutputStream

处理流的父类:FilterInputStream extends InputStream、FilterOutputStream extends OutputStream

 

使用字节流可以读写任意类型的文件
使用字符流只可以读写文本文件(doc不是文本文件)
使用字符流的好处:处理非英文方便
注意:字符流的底层还是字节流

File类

File类用来代表文件或文件夹

作用:

  • 获取文件或文件夹的属性(例如文件名、文件大小等)
  • 实现对文件或文件夹的创建和删除

注意:File类不能对文件内容进行操作,内容操作要使用io流

常用方法:

public String getName():获取文件或文件夹的名称,不包含上级路径
public String getAbsolutePath():获取文件的绝对路径,与文件是否存在没关系
public long lastModified():获取最后一次被修改的时间
public long length():获取文件的大小(字节数)

public boolean exists():文件或文件夹是否存在
public boolean isFile():是否是一个文件,如果不存在,则始终为false
public boolean isDirectory():是否是一个目录,如果不存在,则始终为false

public boolean delete():删除文件或者一个空文件夹,不能删除非空文件夹
public void deleteOnExit():退出时删除文件或者文件夹,用于删除临时文件,无返回值

 

FileInputStream和FileOutputStream

文件字节流

FileInputStream和FileOutputStream是字节流、节点流,数据源和目的地是文件

//创建输入流和输出流
InputStream input = new FileInputStream("e:/in.txt");
OutputStream output = new FileOutputStream("e:/out.txt");
//使用输入流和输出流完成文件复制
int n;				//定义一个中转站
n = input.read();		//读一个字节,public int read() 方法返回值为int类型
while(n !=-1) {	// n=-1 表示读到了文件末尾
	out.write(n);			//写一个字节
	n = input.read();		//再读一个字节
}
//关闭输入流和输出流
input.close();
output.close();

  

缺点:中转站太小,速度慢,效率低 ;可以将中转站由一个字节变为一个字节数组,减少读写硬盘次数

 

//创建输入流和输出流
InputStream input = new FileInputStream("e:/in.txt");
OutputStream output = new FileOutputStream("e:/out.txt");
//使用输入流和输出流完成文件复制
byte[] bytes = new byte[1024];		//定义一个中转站
int length = input.read(bytes);		//将读取的文件内容放入到字节数组中,返回读取的字节数
while(length != -1) {
	out.write(bytes, 0, length);			//将字节数组内容写入文件
	length = input.read(bytes);		//再读内容到一个字节数组
}
//关闭输入流和输出流
input.close();
output.close();

  

FileReader和FileWriter

文件字符流

FileReader和FileWriter是字符流、节点流,数据源和目的地是文件

//创建输入流和输出流
Reader input = new FileReader("e:/in.txt");
Writer output = new FileWriter("e:/out.txt");
//使用输入流和输出流完成文件复制
int n;				//定义一个中转站
n = input.read();		//读一个字符,public int read() 方法返回值为int类型
while(n !=-1) {	// n=-1 表示读到了文件末尾
	out.write(n);			//写一个字符
	n = input.read();		//再读一个字符
}
//关闭输入流和输出流
input.close();
output.close();

  

//创建输入流和输出流
Reader input = new FileReader("e:/in.txt");
Writer output = new FileWriter("e:/out.txt");
//使用输入流和输出流完成文件复制
char[] chars = new char[1024];		//定义一个中转站
int length = input.read(chars);		//将读取的文件内容放入到字符数组中,返回读取的字符数
while(length != -1) {
	out.write(chars, 0, length);			//将字符数组内容写入文件
	length = input.read(chars);		//再读内容到一个字符数组
}
//关闭输入流和输出流
input.close();
output.close();

  

BufferedInputStream和BufferedOutputStream

只使用文件字节流的方式的局限是要从硬盘中读取数据到中转站,而硬盘读取速度是远远低于内存的,因此如果文件较大,则需要多次将数据从硬盘读取到中转站

使用缓冲流的话会在内存中创建输入缓冲区和输出缓冲区,中转站从输入缓冲区读取数据,即从内存到内存,因此可以提高效率

技术分享图片

刷新输出缓冲区

方法一:bufferedOutput.close();底层会关闭流之前主动调用flush()

方法二:主动调用 bufferedOutput.flush();

方法三:缓冲区满了会自动刷新

//创建输入流和输出流
InputStream input = new FileInputStream("e:/in.txt");
OutputStream output = new FileOutputStream("e:/out.txt");
BufferedInputStream bufferedInput = new BufferedInputStream(input);
BufferedOutputStream bufferedOutput = new BufferedOutputStream(output);
//使用输入流和输出流完成文件复制
int n;				//定义一个中转站
n = bufferedInput.read();		//读一个字节,public int read() 方法返回值为int类型
while(n !=-1) {	// n=-1 表示读到了文件末尾
	bufferedOutput.write(n);			//写一个字节
	n = bufferedInput.read();		//再读一个字节
}
//关闭输入流和输出流
bufferedInput.close();
bufferedOutput.close();

  

BufferedReader和BufferedWriter

readLine()底层原理

底层还是一个一个字符地读取,使用StringBuilder的append方法进行拼接操作,遇到换行符后,将StringBuilder(char [])转换为String并返回

 

注意:不同操作系统中换行符是不同的

Unix系统中 "\n"

Windows系统中 "\r\n"

Mac系统中 "\r"

//创建输入流和输出流
BufferedReader reader = new BufferedReader(new FileReader("e:/in.txt"));
BufferedWriter writer = new BufferedWriter(new FileWriter("e:/out.txt"));
//使用输入流和输出流(按行读写)
String line = reader.readLine();	//先读一行
while(line != null) {
	writer.write(line);			//写一行
	writer.newLine();				//换行
	line = reader.readLine();		//再读一行
}
//关闭输入流和输出流
reader.close();
writer.close();

  

 

ObjectInputStream和ObjectOutputStream

文件流、缓冲流读取文件只能按照字节、字节数组方式读取

数据流(DataInputStream和DataOutputStream)和对象流(ObjectInputStream和DataOutputStream)可以实现对各种基本类型和引用类型数据的读写,并保留其本身的类型

 

数据量只能操作基本数据类型和字符串,对象流还可以操作对象(数据流和对象流的使用方式差不多)

写入的是二进制数据,需要通过对应的输入流来读取

使用对象流读写引用类型的数据,需要相应类实现Serializable接口

 

import java.io.*;

public class mytest {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        write();
        read();
    }

    public static void read() throws IOException, ClassNotFoundException {
        InputStream inputStream = new FileInputStream("e:/out.txt");
        BufferedInputStream bis = new BufferedInputStream(inputStream);
        ObjectInputStream ois = new ObjectInputStream(bis);
        //使用输出流
        System.out.println(ois.readBoolean());
        System.out.println(ois.readDouble());
        System.out.println(ois.readUTF());
        System.out.println(ois.readObject());
        System.out.println(ois.readObject());
        //关闭输出流
        ois.close();
    }

    public static void write() throws IOException {
        //创建一个输出流
        OutputStream outputStream = new FileOutputStream("e:/out.txt");
        BufferedOutputStream bos = new BufferedOutputStream(outputStream);
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        //使用输出流
        oos.writeBoolean(true);
        oos.writeDouble(12.6f);
        oos.writeUTF("北京");
        oos.writeObject(new User("唐三藏", 18));
        oos.writeObject(new User("x", 25));
        //关闭输出流
        oos.close();
    }
}


class User implements Serializable{
    String name;
    int age;

    public User() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

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

    @Override
    public String toString() {
        return "User{" +
                "name=‘" + name + ‘\‘‘ +
                ", age=" + age +
                ‘}‘;
    }
}

  

其他流

打印流

PrintStream和PrintWriter

只有输出流,没有输入流

PrintStream 可以将各种类型的数据写入文件,不能保留原来的类型,都编程String类型

转换流

InputStreamReader和OutputStreamWriter

实现字节流到字符流的转换,是适配器模式的应用

只能从字节流转换为字符流,可以带来处理字符的便利;没有字符流转换为字节流的转换流,因为没有这种需求

 

字节数组流

ByteArrayInputStream和ByteArrayOutputStream是字节流、节点流,数据源和目的地都是一个字节数组

CharArrayReader和CharArrayWriter是字符流、节点流,数据源和目的地是一个字符数组

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

//创建输入流和输出流InputStream input = new FileInputStream("e:/in.txt");OutputStream output = new FileOutputStream("e:/out.txt");BufferedInputStream bufferedInput = new BufferedInputStream(input);BufferedOutputStream bufferedOutput = new BufferedOutputStream(output);//使用输入流和输出流完成文件复制int n;//定义一个中转站n = bufferedInput.read();//读一个字节,public int read() 方法返回值为int类型while(n !=-1) {// n=-1 表示读到了文件末尾bufferedOutput.write(n);//写一个字节n = bufferedInput.read();//再读一个字节}//关闭输入流和输出流bufferedInput.close();bufferedOutput.close();

I/O流

原文:https://www.cnblogs.com/tang321/p/14800040.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!