java IO学习总结

Java程序中,对于数据的输入/输出操作都是以"流"的方式进行。设备可以是文件,网络,内存等流具有方向性,至于是输入流还是输出流则是一个相对的概念,一般以程序为参考,如果数据的流向是程序至设备,我们成为输出流,如果数据的流向是设备至程序称为输入流。
java IO 结构类图

一、流的分类
1)按照流的方向分为输入流和输出流。
2)按照处理数据的单位不同分为字节流和字符流(字节流读取的最小单位是一个字节(1byte=8bit),而字符流一次可以读取一个字符(1char = 2byte = 16bit))。
3)按照功能的不同分为节点流和处理流(节点流是可以"直接"从一个数据源中读写数据的流。处理流也可以称为功能流或者包装流,它是可以对节点流进行封装的一种流,封装后可以增加节点流的功能)。例如FileInputStream是一个节点流,可以直接从文件中读取数据,而BufferedInputStream可以包装FileInputStream,使得其有缓冲数据的功能。
二、java.io包常用的流
不管流的分类是多么的丰富和复杂,其根源来自于四个基本的父类
字节输入流:InputStream 字节输出流:OutputStream 字符输入流:Reader 注:这四个父类都是抽象类
三、字节流InputStream和OutputStream
1)InputStream
//从输入流中读取数据的下一个字节,如果到达流的末尾则返回 -1
public abstract int read();
//把读到的字节存到字节数组b中,并返回本次读到了多少个字节
public int read(byte[] b){…}
//把读到的字节存到字节数组b中,同时指定开始存的位置以及最大字节数,并返回本次读到了多少个字节
public int read(byte[] b,int off,int len){…}
//返回此输入流下一个方法调用可以不受阻塞地从此输入流读取(或跳过)的估计字节数
public int available(){…}
//跳过此输入流中数据的 n 个字节
public long skip(long n){…}
//关闭此输入流并释放与该流关联的所有系统资源
public void close(){…}
//测试此输入流是否支持 mark 和 reset 方法
public boolean markSupported(){…}
2)OutputStream
//将指定的字节写入此输出流
public abstract void write(int b);
//将字节数组b中的所有字节写入此输出流
public void write(byte[] b){…}
//将字节数组b中的字节写入此输出流,指定开始位置及最大字节数
public void write(byte[] b,int off,int len){…}
//刷新此输出流并强制写出所有缓冲的输出字节
public void flush(){…}
//关闭此输出流并释放与此流有关的所有系统资源
public void close(){…}
3)InputStream的子类和OutputStream的子类几乎都是成对出现的,一个负责读数据的工作,一个负责写数据的工作。
例:使用字节流复制图片

package ch02;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/*
 * 使用FileInputStream和FileOutputStream
 * 复制图片
 */
public class CopyImage {
	public static void main(String[] args) throws IOException {
		FileInputStream fin = new FileInputStream("C:/Users/Image.jpg");
		FileOutputStream fout = new FileOutputStream("C:/Users/ImagegCopy.jpg");
		int len = 0;
		byte[] buff = new byte[1024];
		while ((len = fin.read(buff)) != -1) {
			fout.write(buff, 0, len);
		}
		fin.close();
		fout.close();
	}
}

四、字符流Reader和Writer
1)字符流Reader
public int read(){…}
public int read(char[] cbuf){…}
public abstract int read(char[] cbuf, int off,int len){…}
//指定缓冲区
//@since 1.5
public int read(CharBuffer target){…}
abstract public void close();
public long skip(long n){…}
public boolean markSupported(){…}
public void mark(int readAheadLimit){…}
public void reset(){…}
//Tells whether this stream is ready to be read
public boolean ready(){…}
2)字符流Writer
public void write(int c){…}
public void write(char cbuf[]){…}
abstract public void write(char cbuf[], int off, int len);
public void write(String str){…}
public void write(String str, int off, int len){…}
abstract public void flush();
abstract public void close();
//@since 1.5
//和out.write©的效果一样
public Writer append(char c){…}
public Writer append(CharSequence csq){…}
public Writer append(CharSequence csq, int start, int end){…}
五、字节缓冲流BufferedInputStream和BufferedOutputStream
public class BufferedInputStream extends FilterInputStream
BufferedInputStream 为另一个输入流添加一些功能,即缓冲输入以及支持 mark 和 reset 方法的能力。在创建 BufferedInputStream 时,会创建一个内部缓冲区数组。在读取或跳过流中的字节时,可根据需要从包含的输入流再次填充该内部缓冲区,一次填充多个字节。
public class BufferedOutputStream extends FilterOutputStream
该类实现缓冲的输出流。通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必针对每次字节写入调用底层系统。
例:使用字节缓冲流实现图片的复制

package ch02;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/*
 * 使用BufferedInputStream和BufferedOutputStream
 * 复制图片
 */
public class CopyBImage {
	public static void main(String[] args) throws IOException {
		BufferedInputStream bfin = new BufferedInputStream(
				new FileInputStream("C:/Users/iamge.jpg"));
		BufferedOutputStream bfout = new BufferedOutputStream(
				new FileOutputStream("C:/Users/CopyIamge.jpg"));
		int len = 0;
		byte[] buff = new byte[1024];
		while ((len = bfin.read(buff)) != -1) {
			bfout.write(buff, 0, len);
		}
		bfin.close();
		bfout.close();
	}
}

六、转换流
InputStreamReader和OutputStreamWriter是一对名字中既有Stream,又有Reader或Writer的流,因为它们是转换流,负责把一个字节流转换为字符流。所以它们是字节流和字符串之间的桥梁.注:在把字节流转换为字符流的过程中,还可以指定字符编码,避免乱码的出现。
为了获得最高效率,可考虑将 OutputStreamWriter 包装到 BufferedWriter 中

Writer out = new BufferedWriter(new OutputStreamWriter(System.out))

七、对象流
1)序列化和反序列化
Java中的序列化是指把Java对象转换为字节序列的过程
对象—序列化—>01010101
Java中的反序列化是指把字节序列恢复为Java对象的过程
01010101—反序列化—>对象
思考:为什么需要序列化和反序列化?
为了方便项目的传输;
2)如何实现序列化和反序列化
使用对象流即可实现对象的序列化和反序列化
ObjectOutputStream类中的方法可以完成对象的序列化:
public final void writeObject(Object obj){…}
ObjectInputStream类中的方法可以完成对象的反序列化:
public final Object readObject(){…}
注:这俩个对象流都属于字节流
八.随机访问流
java.io.RandomAccessFile类
public class RandomAccessFile extends Object{…}
这是个特殊的流,它不属于之前那些流的体系。
这个流的既可以用来读文件,也可以用来给文件中写内容,并且该类中的方法可以用来定位文件中的位置:
public native void seek(long pos); long pos 字节数
构造器中需要设置该流的操作模式:
//对文件只读
RandomAccessFile r = new RandomAccessFile(filePath,“r”);
//对文件即可读又可写
//但是一旦确定了读或者写,那么就不能在变
RandomAccessFile rw = new RandomAccessFile(filePath,“rw”);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值