java IO流详细总结(一、字节输入输出流)

本文介绍了Java IO流,它是数据在内存与外部存储设备间传输的通道。按方向、单位、功能划分有不同类型。还介绍了常用类库和字节输入输出流对象,如InputStream/OutputStream及其子类。最后说明了用FileInputStream和FileOutputStream实现文件复制,可借助过滤流提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、什么是IO流:
将数据从内存传输到外部存储设备的通道,管道。
IO流的分类
1.按方向划分:<以JVM为参照物>
输入流:将<外部存储设备>中的数据读入到<内存>中。
输出流:将<内存>中的数据写入到<外部存储设备>中。

2.按单位划分:
字节流:以字节(8bit)为单位,能够传输所有类型的文件。
字符流:以字符为单位,一次可能读多个字节。.只能传输文本文件(能够被记事本打开.java/.txt/.html,并且不改变内容的文件)

只要是处理纯文本数据,就优先考虑使用字符流。 除此之外都使用字节流。

3.按功能划分:
节点流:具有基本的读写功能
过滤流:在节点流的基础上,增加了新的功能

二、IO流常用类库:
IO流常用类库
三、java IO流对象
1.字节输入(输出)流InputStream/OutputStream中输入字节流的继承图可见上图,可以看出:

  1. InputStream/OutputStream 是所有的输入(输出)字节流的父类,它是一个抽象类。
  2. 常用子类FileOutputStream:文件字节输出流
    常用方法为:(返回值类型都为void)
			void write(int b):向外部存储设备中写入数据
			void write(byte[] b) :向指定文件中写入 数组长度个 字节
			void write(byte[] b, int off, int len) :向指定文件中写入数组中指定的字节
						b:数组  off:开始下标   len:个数
			void close(): 关闭资源

FileInputStream:文件字节输入流
常用方法: (返回值类型都为int)

			int read():从输入流中读取一个字节,返回值表示字符的整数表现形式,若没有字符  则返回-1
			int read(byte[] b):从输入流中读取多个字节,返回值表示读取的有效字节个数
			int read(byte[] b, int off, int len) :
				b:数组  off:存储到数组的指定下标  len:存储个数

  1. BufferedOutputStream/BufferedInputStream、DataOutputStream/DataInputStream、ObjectOuputStream/ObjectInputStream都是字节过滤流。
    其中,BufferedOutputStream/BufferedInputStream 字节输入输出过滤缓冲流,可以提高IO的效率,减少磁盘的访问次数。数据存储在数据缓冲区中,需要使用flush方法 清空缓冲区。也可以直接使用close方法。
    例如:
package test;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * @author 超伟
 * @date 2019年5月16日  
 * @博客: https://blog.youkuaiyun.com/MacWx  
 */
public class testOutput {
	public static void main(String[] args) throws IOException {
		//创建文件输出流
		FileOutputStream fo = new FileOutputStream("file/test.txt");
		//往文件中写入一个char数据,
		fo.write(65);
		//创建一个byte类型数组
		byte[] b = new byte[]{66,67,68,69};
		//将此数组写入到文件中
		//fo.write(b);
		//将此数组中的下标为1的开始,的后两个字符写入到文件中
		fo.write(b, 0, 4);
		//关闭输出流
		fo.close();
		//FileOutputStream的两参构造方法,第一个参数传的是文件名,
		//第二个参数如果是true,则使文件添加,否则覆盖!
		FileOutputStream file = new FileOutputStream("file/test.txt",true);
		String s  = "今天星期五";
		byte[] cs = s.getBytes();
		//将字符串数组添加写入文件中
		file.write(cs);
		//关闭流
		file.close();
	}
}

上面程序是将一个自定义的字符或者字符串通过FileOutputStream写入到文件中去的,那么怎么从一个文件中把数据读取到java虚拟机JVM并通过控制台打印出来呢?

package test;

import java.io.FileInputStream;
import java.io.IOException;

/**
 * @author 超伟
 * @date 2019年5月16日  
 * @博客: https://blog.youkuaiyun.com/MacWx  
 */
public class testInput {
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		//创建文件读入流
		FileInputStream f = new FileInputStream("file/test.txt");
		//返回读入文件的整数表现形式
		//int read = f.read();
		byte b[] = new byte[3];
		//测试通过数组读取文件中的信息
		//f.read(b,0,2);
		//再通过死循环遍历读入的文件所有内容,
		//如果到最后一个字节为空即等于-1的时候break跳出循环
		while(true){
			int reads = f.read();
			if (reads== -1) {
				break;//跳出死循环
			}
			//输出读取到的字节,再强转回char类型
			System.out.print((char)reads);
		}
		//关闭资源
		f.close();
	}
}

DataOutputStream/DataInputStream 主要用来操作基本数据类型,和字符串的输入输出。

import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class TestDataOuputStream {
	public static void main(String[] args) throws IOException {
		//创建节点流
		FileOutputStream fileOutputStream = new FileOutputStream("file/f.txt");
		//创建过滤流
		DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream);
		//写操作,往文件中写入浮点数12.5;
		dataOutputStream.writeDouble(12.5);
		//关闭资源
		dataOutputStream.close();
	}
}

ObjectOuputStream/ObjectInputStream 对象输入输出过滤流,主要增强缓冲区的功能,同时增强了操作基本数据类型和字符串类型的能力
可以操作对象
writeObject(Object obj):向外部存储设备写入对象数据类型
Object readObject():从外部存储设备读入对象,返回值为读入的对象

对象放在流上进行传输的过程称为对象序列化。

要求:自定义的类必须实现Serializable接口

需要注意:
i.被transient修饰的属性,不参与序列化
ii. java.io.EOFException 文件到达尾部
文件中只有一个对象,连续读取两次 就会报此异常
iii.如果参与序列化对象有对象类型的属性,则这个属性类型也必须实现Serializable
iv.当序列化对象为集合时,它的对象元素类型,也必须实现Serializable接口


import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class TestObjectOutputStream {
	public static void main(String[] args) throws IOException {
		//创建节点流
		FileOutputStream fileOutputStream = new FileOutputStream("file/d.txt");
		//创建包装、过滤流
		ObjectOutputStream oos = new ObjectOutputStream(fileOutputStream);
		//执行写操作
		//写入一个对象
		Student s = new Student("macw",22);
		oos.writeObject(s);
		//关闭资源
		oos.close();
	}
}

class Student implements Serializable{  //对学生对象 实现了序列化
	
	private static final long serialVersionUID = 1L;
	private String name;
	private transient int age;   //被transient修饰的属性,不参与序列化
	private Address add = new Address();
	
	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 Student() {
		super();
	}
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}
}
class Address implements Serializable{}

谈一下使用IO流进行文件复制的操作:
用FileInputStream 和 FileOutputStream 实现文件的复制。
其基本实现流程为先使用FileInputStream.read()方法读取到文件中的数据,再将读取到JVM中的数据通过FileOutputStream.write()方法写入到想要复制的文件中。
还可以实现字节包装类(过滤流也加包装类,同一个意思)来增强缓冲区的功能,提高IO的效率,减少磁盘的访问次数。
例如:
使用IO流将图片“gril.jpg”复制到“file”文件下

package work;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * @author 超伟
 * @date 2019年5月16日  
 * @博客: https://blog.youkuaiyun.com/MacWx  
 */
public class t11 {

	public static void main(String[] args) throws IOException {
		//创建文件字节输入流对象,
		FileInputStream fileInputStream = new FileInputStream("E:\\java\\练习\\gril.jpg");
		//创建文件字节输出流对象,
		FileOutputStream fileOutputStream = new FileOutputStream("file/gril.jpg");
		//分别对输入输出流对象通过过滤流进行包装,提高IO的效率
		BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
		BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
		//记录程序运行开始复制时的当前时间,目的是为了测试本次复制效率如何
		long start = System.currentTimeMillis();
		//通过死循环遍历原文件中的每一个字节,遍历到最后字节为空即等于-1时跳出死循环
		while (true) {
			int read = bufferedInputStream.read();
			if (read == -1) {
				break;
			}
			//将读取到的每一个字节一次写入到复制的新文件中
			bufferedOutputStream.write(read);
		}
		//关闭所有流资源
		bufferedInputStream.close();
		bufferedOutputStream.close();
		long end = System.currentTimeMillis();
		//通过程序结束时的当前时间减去开始时间查看复制效率
		System.out.println(end - start);
	}

}

这样就可以完成文件的简单复制操作了!

由于篇幅限制下一篇介绍IO流的字符输入输出流…

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里马不常有

整理不易,点滴助力就是不竭动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值