Java 流(Stream)、文件(File)和IO

原文 链接Java 流(Stream)、文件(File)和IO

Java IO流

I/O类库中使用“流”这个抽象概念。Java对设备中数据的操作是通过流的方式。表示任何有能力产出数据的数据源对象,或者是有能力接受数据的接收端对象。“流”屏蔽了实际的I/O设备中处理数据的细节。IO流用来处理设备之间的数据传输。设备是指硬盘、内存、键盘录入、网络等。

  1. IO流分类
    -根据数据类型的不同分为:字符流和字节流
    -根据数据的流向分为:输入流和输出流

深入浅析Java中 IO流的继承结构

InputStream 与 OutputStream是一套字节输入-输出体系
Reader 与 Writer 是一套字符输入-输出体系

InputStream 与 OutputStream继承结构

InputStream和OutputStream抽象类是表示一个字节输入输出流的所有类的超类。
需要定义InputStream子类的输入流必须始终提供返回输入下一个字节的方法。
需要定义OutputStream子类输出流接受输出字节并将它们发送到某个接收器。
 

常用字节流类分析

  1. InputStream 抽象类
 
//从输入流中读取一定数量的字节,并将它们存储到缓冲区数组b中。实际读取的字节数作为整数返回。
//此方法会阻塞,直到输入数据可用,检测到文件结尾或引发异常为止。
//如果b的长度为零,则不读取字节并返回0; 否则,尝试读取至少一个字节。如果由于流位于文件末尾而没有可用的字节,则返回值 -1; 否则,至少一个字节被读取并存储到b中。
//第一个字节读取存储到元素b[0] 中,下一个字节存储到b[1] 中,依此类推
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
//根据后面实现,一般是一次读取一个
public abstract int read() throws IOException;
//从off位置开始放字节
public int read(byte b[], int off, int len) throws IOException;
//跳过并丢弃该输入流中的n字节数据。
public long skip(long n) throws IOException;
//关闭io流
public void close() throws IOException {};

主要子类
1) FileInputStream:把一个文件作为InputStream,实现对文件的读取操作

 
public FileInputStream(String name) throws FileNotFoundException {
this(name != null ? new File(name) : null);
}
public FileInputStream(File file) throws FileNotFoundException;

2) ByteArrayInputStream:把内存中的一个缓冲区作为InputStream使用
3) StringBufferInputStream:把一个String对象作为InputStream
4) PipedInputStream:实现了pipe的概念,主要在线程中使用
5) SequenceInputStream:把多个InputStream合并为一个InputStream
6) ObjectInputStream :按对象读取,对象需要实现序列化接口
2. OutputStream抽象类

 
//将指定的字节写入此输出流。write的一般契约是将一个字节写入输出流。
public abstract void write(int b) throws IOException;
//从指定的字节数组中写入b.length字节。write(b) 的一般契约是,它应该与调用write(b,0,b.length) 具有完全相同的效果。
public void write(byte b[]) throws IOException {
write(b, 0, b.length);
}
//刷新此输出流并强制写出缓冲的输出字节。flush的一般契约是,调用它表示,如果先前写入的任何字节已被输出流的实现缓冲,则应立即将这些字节写入其预期目标。
public void flush() throws IOException {
}
public void close() throws IOException {
}

主要的子类

  1. ByteArrayOutputStream:把信息存入内存中的一个缓冲区中
  2. FileOutputStream:把信息存入文件中
 
//是否追加
public FileOutputStream(String name, boolean append);
  1. PipedOutputStream:实现了pipe的概念,主要在线程中使用
  2. SequenceOutputStream:把多个OutStream合并为一个OutStream
  3. ObjectOutputStream :按对象输出,对象需要实现序列化接口

重点:缓冲输入输出流 BufferedInputStream/ BufferedOutputStream

BufferedInputStream:当向缓冲流写入数据时候,数据先写到缓冲区,待缓冲区写满后,系统一次性将数据发送给输出设备。
BufferedOutputStream :当从向缓冲流读取数据时候,系统先从缓冲区读出数据,待缓冲区为空时,系统再从输入设备读取数据到缓冲区。

BufferedInputStream

 
//默认大小,最大是Integer.MAX_VALUE - 8;
private static int DEFAULT_BUFFER_SIZE = 8192;
//缓冲区
protected volatile byte buf[];
public BufferedInputStream(InputStream in) {
this(in, DEFAULT_BUFFER_SIZE);
}
public BufferedInputStream(InputStream in, int size) {
super(in);
if (size <= 0) {
throw new IllegalArgumentException("Buffer size <= 0");
}
buf = new byte[size];
}
//具体实例
File srcFile=new File("hello.txt");
File srcFile1=new File("hello2.txt");
FileInputStream fis=new FileInputStream(srcFile);
FileOutputStream fw=new FileOutputStream(srcFile1);
BufferedInputStream bis=new BufferedInputStream(fis);
BufferedOutputStream bos=new BufferedOutputStream(fw);
byte[] ch=new byte[5];
int len;
while((len=bis.read(ch))!=-1)
{
bos.write(ch,0,len);
}
bos.close();
bis.close();

BufferedOutputStream

 
//其他类似
public synchronized void flush() throws IOException {
flushBuffer();
out.flush();
}
//刷新此缓冲的输出流。这将强制将任何缓冲的输出字节写入基础输出流。

小结

Stream都是针对字节流的,BufferedOutputStream和BufferedOutputStream类BufferedOutputStream:缓冲字节输出流是一个高级流,与其他低级流配合使用。它们内部有一个缓冲区,用来提高处理效率。读取或输出数据时,先存放在缓冲区,当缓冲区满时,或者调用flush方法,缓冲输出流会将数据写出。对于小文件可能看不到性能的提升。但是文件稍微大一些的话,就可以看到实质的性能提升了。

Writer和Reader继承结构


Writer用于写入字符流的抽象类。子类必须实现的唯一方法是write(char[],int,int),flush() 和close()。
Reader用于读取字符流的抽象类。子类必须实现的唯一方法是read(char[],int,int) 和close()。

常用Reader流

 
//用于同步此流上的操作的对象。为了提高效率,字符流对象可以使用除其自身以外的对象来保护关键部分
protected Object lock;
//构造函数
protected Reader(Object lock) ;
protected Reader() {
this.lock = this;
}
//没什么特别的
abstract public void close() throws IOException;
abstract public int read(char cbuf[], int off, int len);
public int read(char cbuf[]) throws IOException;
private char skipBuffer[] = null;
//跳过字符。此方法将阻塞,直到某些字符可用,出现I/O错误或到达流结束为止。
public long skip(long n) throws IOException;

子类:
(1) 用指定字符数组作为缓存参数:CharArrayReader(char[])
将字符数组作为输入流:public CharArrayReader(char buf[], int offset, int length)
2) CharArrayReader:此类实现了一个字符缓冲区,可以用作字符输入流
3) StringReader :源为字符串的字符流
4) InputStreamReader
InputStreamReader是从字节流到字符流的桥梁: 它读取字节并使用指定的字符集将它们解码为字符。
5) FilterReader: 允许过滤字符流
protected filterReader(Reader r);
6) BufferReader :接受Reader对象作为参数,并对其添加字符缓冲器,使用readline()方法可以读取一行。
Public BufferReader(Reader r);
String readLine(boolean ignoreLF)
ignoreLF – If true, the next '\n' will be skipped
7) FileReader 用于读取字符文件的便利类。此类的构造函数假定默认字符编码和默认字节缓冲区大小是适当的。需要指定的化需要 InputStreamReader on a FileInputStream.

Write常用流

 
//用于保存字符串和单个字符的写入的临时缓冲区
private char[] writeBuffer;
private static final int WRITE_BUFFER_SIZE = 1024;
protected Object lock;
//Writes an array of characters.
public void write(char cbuf[]) throws IOException {
write(cbuf, 0, cbuf.length);
}
abstract public void write(char cbuf[], int off, int len) throws IOException;
public void write(String str) throws IOException {
write(str, 0, str.length());
}
//追加
public Writer append(CharSequence csq) throws IOException {
if (csq == null)
write("null");
else
write(csq.toString());
return this;
}
abstract public void flush() throws IOException;
abstract public void close() throws IOException;

子类:

1) FileWrite: Convenience class for writing character files.
2) chararrayWrite:This class implements a character buffer that can be used as an Writer.
3) PrintWrite:生成格式化输出
   public PrintWriter(outputstream os);
4) filterWriter:用于写入过滤字符流
   protected FilterWriter(Writer w);
5) PipedWriter:写入管道
6) StringWriter:字符串写入
7)BufferedWriter:将文本写入字符输出流,缓冲字符,以便有效地写入单个字符,数组和字符串。
public void newLine()写入一个行分隔符。

 
//常用法
//不存在就创建
File file=new File("hello1.txt");
FileWriter fw=new FileWriter(file);
fw.write("asdfghjkl;\n");
fw.write("12231232123");
fw.close();

小结

对于字符流,如果对于大文件推荐使用缓存BufferedWriter,和BufferedReader。

总结

  1. 需要较高的读写速度
    使用缓存BufferedInputStream, BufferedOutputStream,( 字节流 ) BufferedReader, BufferedWriter( 字符流 ),注意:当缓冲区未写满的情况下,需要flush去清空缓存写入。
    当然close函数有运行flush,读取的化会返回读取长度。
  2. 对于文件操作
    FileInputStream, FileOutputStream, ( 字节流 )FileReader, FileWriter( 字符 )
  3. 网络数据流
    InputStream, OutputStream,( 字节流 ) Reader, Writer( 字符流 )
  4. 特殊需要:
    从 Stream 到 Reader,Writer 的转换类: InputStreamReader, OutputStreamWriter
    对象输入输出: ObjectInputStream, ObjectOutputStream
    进程间通信: PipeInputStream, PipeOutputStream, PipeReader, PipeWriter
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值