文档章节

Java IO 理论笔记

五大三粗
 五大三粗
发布于 2015/02/11 20:12
字数 3093
阅读 278
收藏 32

1、Java IO 流

io是java中实现输入输出的基础,它可以很方便的完成数据的输入输出操作,Java把不同的输入输出抽象为流,通过流的方式允许Java程序使用相同的方式来访问不同的输入、输出。

2、流的分类

输入流、输出流 

A、输入流:只能从中读取数据,而不能向里面写数据

B、 输出流:只能向里面写数据,而不能读数据

可以这样理解,数据从内存到硬盘,通常认为是输出流,即写操作;相反,从硬盘到内存,通常认为是输入流,即读操作;这里的输入、输出是从内存的角度划分的

Java的输入流主要有InputStream和Reader作为基类,而输出流则主要由OutputStream和Writer作为基类;

 

字节流和字符流

字节流和字符流区别非常简单,它们的用法几乎一样。区别在于字节流和字符流所操作的数据单元不同:字节流操作的最小单元数据是8位字节,而字符流作为最小数据单元是16为字节。

字节流主要由InputStream、OutputStream作为基类,而字符流则主要由Reader和Writer作为基类完成。

节点流和处理流

按照流的角色分,可以分为节点流和处理流。

可以从、向一个特定的IO设备,读写数据流,称为节点流,节点流常常也被常务低级流(Low Level Stream)

处理流则用于对一个已经存在的流进行连接封装,通过封装后来实现数据的读写功能。处理流称为高级流;

当用处理流的进行输入、输出时,程序并不会直接连接到实际数据源,没有和实际的输入、输出节点连接。使用处理流一个明显的好处是:只要使用相同的处理流,程序就可以采用相同的输入、输出代码来访问不同数据源,随着处理流锁包装节点流的改变,程序实际所访问的数据源也相应发生改变。

处理流的功能主要体现在两个方面:

性能提高:主要以增加缓冲方式来提高输入、输出的效率

操作的便捷: 处理流可能提供了系列便捷的方法来一次性输入、输出大批量的内容,而不是输入、输出一个或多个单位数据

处理流可以“嫁接”在任何已经存在的流的基础上,这就允许Java应用程序采用相同的代码、透明的方式来访问不同的输入、输出设备输入流。

字节输入流InputStream和字符输入流Reader

InputStream和Reader是所有输入流的基类,他们都是2个抽象类,本身并不能创建实例来执行输入,但他们有输入流的模版,所以它们的方法是所有的输入流和输出流可以用的方法。

在InputStream里常用的方法:

int read(): 从输入流中读取单个自己

int read(byte[] b): 从输入流中读取最多b.length个字节,将读取的字节存在数组b中,返回实际读取的字节数

int read(byte[] b, int off, int len): 从输入流中读取最多len个字节数据,并将其存储在数字b中,放入b数组中时,并不是从数组起点开始,而是从off位置开始,返回实际读取字节数。

在Reader里经常使用的方法:

int read(): 从输入流中读取单个字符

int read(char[] c): 从输入流读取最多c.length个字符数据,并将其存储在字符数组c中,返回实际读取的字符

int read(char[] c, int off, int len): 从输入流中读取最多len个字符的数据,将读取的数据放到字符数组c中保存,从数组的off开始读取;

InputStream、Reader还支持如下几个方法移动指针:

void mark(int readAheadLimit): 在记录指针当前位置第一个标记(mark)

boolean markSupported(): 判断此输入流是否支持mark()操作,即是否支持记录标记

void reset():将此流的记录的指针重新定位到上一次记录的标记的位置

long skip(long n):记录指针向前移动n个字节、字符

OutputStream字节输出流和Writer字符输出流

具有以下方法:

void write(int c): 指定的字节、字符输出到输出流中

void write(byte[]/char[] buf): 将字节数组/字符数组中的数据传输到指定输出流中

void write(byte[]/char[] buf, int off,int len):将指定数组中的数据输出到指定输出流中

字符输出流还有以下方法:

void write(String s):将指定字符串输出到指定输出流中

void write(String s, int off, int len):将字节数组、字符数组中从off位置开始,长度为len的字节、字符输出到输出流中

3、Java的输入、输出流:

分类

字节输入流

字节输出流

字符输入流

字符输出流

抽象基类

InputStream

OutputStream

Reader

Writer

访问文件

FileInputStream

FileOutputStream

FileReader

FileWriter

访问数组

ByteArrayInputStream

ByteArrayOutputStream

CharArrayReader

CharArrayWriter

访问管道

PipedInputStream

PipedOutputStream

PipedReader

PipedWriter

访问字符串

   

StringReader

StringWriter

缓冲流

BufferedInputStream

BufferedOutputStream

BufferedReader

BufferedWriter

转换流

   

InputStreamReader

OutputStreamWriter

对象流

ObjectInputStream

ObjectOutputStream

   

抽象基类

FilterInputStream

FilterOutputStream

FilterReader

FilterWriter

打印流

 

PrintStream

 

PrintWriter

推回输入流

PushbackInputStream

 

PushbackReader

 

特殊流

DataInputStream

DataOutputStream

   

输入、输出流的体系:

推回输入流:

有2个特殊流与众不同,就是PushbackInputStream、PushbackReader,它们有以下常用方法:

void unread(byte[]/char[] buf):将一个字节/字符数组推到缓冲区里,运行重复读取推回的内容

void unread(byte[]/char[] buf, int off, int len):将一个字节/字符数组从off位置开始读取,长度是len的字符/字节数组的内容推回到缓冲区中,允许重复刚才读取的内容

void unread(int b):将一个字节、字符推回到缓冲区

这2个推回输入流都带一个缓冲区,当程序调用unread的时候,系统就会把指定数组的内容推回到缓冲区,而推回输入流每次调用read的方法,总会先去读取推回缓冲区中的内容,只有完全读取的缓冲区里面的内容后,而且还没有装满read所需的数组,才会到原输入流中读取内容;

重定向标准输入输出

在System中有3大标准输入、输出方法:

static void setErr(PrintStream e):重定向“标准”错误输出流

static void setIn(InputStream in):重定向“标准”输入流

static void setOut(OutputStream out):重定向“标准”输出流

JVM写其他进程数据

Runtime对象有exec方法,他可以运行jvm命令行,该方法产生一个Process对象,Process对象代表由该Java程序启动的子进程,Process类有以下方法,可以和子进程通信;

InputStream getErrorStream():获取子进程的错误流

InputStream getInputStream():获取子进程的输入流

OutputStream getOutputStream():获取子进程的输入流

4、RandomAccessFile

RandomAccessFile是Java输入、输出体系中功能最丰富的文件内容访问类,它提供了众多方法来访问文件内容,它既可以读文件内容也可以像文件输出数据。它和普通的输入、输出流不同的是,它可以随机访问的方式,操作文件数据。

RandomAccessFile可以自由定位文件指针,所以RandomAccessFile可以不从开始的地方输出,RandomAccessFile可以向已经存在的文件后追加内容。

RandomAccessFile对象包含一个指针用来记录当前读写的位置,当程序新创建一个RandomAccessFile对象时,该指针位于文件头部,既0的位置;当读取或写入了n个字节后,文件指针就指向最后的位置,除此之外,文件指针也是可以随意移动的,RandomAccessFile有以下方法操作指针:

long getFilePointer():返回文件记录指针的当前位置

void seek(long pos):将文件记录指针定位到pos位置

RandomAccessFile既可以读也可以写,所以它包含了完全类似于InputStream的read方法,和OutputStream的write方法,用法和原来的都一样;而且RandomAccessFile还包含了readXxx、writeXxx的输入输出方法;

RandomAccessFile的文件访问模式:

r:以只读方式打开指定文件

rw:以读取、写入方式打开指定文件,如果文件不存在就创建

rws:以读取、写入的方式打开指定文件,相对应rw模式,还要求文件内容和元数据的每个更新都同步写入到底层存储设备

rwd:以读取、写入方式打开指定文件,对于rw,还要求文件内容的每个更新都同步写入到底层设备

5、序列化

在远程调用、分布式开发中常用到序列化,将java对象序列化的文件中保存,然后在解析的时候又反序列化,其中需要用到Serializable接口;在实现了该接口的对象可以顺利序列化成一个文件保存在硬盘上,反序列化也是通过该接口的id来查找该对象的。

transient可以忽略对象中某个属性不被序列化。

6NIO

nio常用的包介绍:

java.io 包:主要提供了一些和Buffer相关的类

java.io.channels:包括Selector和Channel的相关类

java.nio.charset:包含和字符集相关的类

java.nio.channels.spi:提供Channel服务类

java.nio.charset.spi:提供文字集的服务类

Buffer介绍

Buffer是提取数据的容器,这里有ByteBuffer、CharBuffer、ShortBuffer、IntBuffer、LongBuffer、FloatBuffer、DoubleBuffer。

上面这些类,除了ByteBuffer之外,都采用类似的方法管理数据,只是各自管理的数据类型不同而已。这些Buffer都没有构造器,通过使用如下方法来得到一个Buffer对象:

static XxxBuffer allocate(int capacity) 创建一个容量为capacity的XxxBuffer对象

ByteBuffer的子类MappedByteBuffer,它用于表示Chanael将硬盘文件的的部分或全部内容映射到内存中后得到结果,通常MappedByteBuffer对象由Chanael的map方法返回。

在Buffer中有三个重要的概念:容量(capacity)、界限(limit)、位置(position)

容量(capacity):缓冲区的容量(capacity)表示该Buffer的最大数据容量,即最多可以存储多少数据,缓冲区的容量不能为负数,在创建后是不能改变的。

界限(limit):第一个不应该被读出或写入的缓冲区位置索引。也就是说,位于limit后的数据既不能读,也不能写。

位置(position):用于指明下一个可以读出的后者写入的缓冲区位置索引。类似于IO流中的记录指针位置。当刚刚新建一个Buffer对象时,容器position为0,如果从Channel读取了2个数据到该Buffer中,则postion为2,指向Buffer中的第三个。

Buffer常用方法:

int capacity():返回Buffer的capacity的大小

boolean hasRemaining():判断当前位置(position)和界限(limit)之间是否还有元素可以提供处理。

int limit:返回Buffer的界限(limit)的位置

Buffer limit(int newLimit)重新设置界限的值,并返回一个具有新的limit的缓冲区的对象

Buffer mark():设置Buffer的mark位置,它只能在0和位置position之间做mark

int position():返回当前Buffer的position

Buffer postion(int newPostion):设置Buffer的新位置,并返回一个具有新的limit的缓冲区对象。

int remaining():返回当前位置和界限之间的元素个数

Buffer reset():将position位置设置到mark的位置

Buffer rewind():将位置(position)设置为0,取消设置的mark

当使用put和get来访问Buffer中的数据时,分为绝对和相对的2种:

相对的Relative:从Buffer中的当前位置读取和写入数据,然后将位置(position)的值按处理元素的个数相加。

绝对Absolute:直接根据索引来向Buffer中读取或写入数据,使用绝对方式来访问Buffer理的数据,并不会影响位置position的值。

© 著作权归作者所有

共有 人打赏支持
五大三粗
粉丝 160
博文 2264
码字总数 4712446
作品 0
广州
程序员
私信 提问
java基础io流——配角也风流(不求甚解)

本章简单介绍几个常见的io流派生。 1:数据操作流(操作基本类型数据的流)(理解) 代码示例: 2:内存操作流(理解) 用于处理临时存储信息的,程序结束,数据就从内存中消失。 代码示例: 注:查看...

潇潇漓燃
05/30
0
0
JAVA NIO编程入门(一)

JAVA NIO编程入门(一) 一、前言 笔者之前接触的NIO编程比较少,所以对这一块的基础也比较弱,NIO作为java编程中一个重要的模块,不能很好的掌握它,感觉自己在java方面就掌握的不够,所以,...

木木匠
09/01
0
0
Java NIO ByteBuffer学习

深入理解Apache Mina (6)---- Java Nio ByteBuffer与Mina ByteBuffer的区别 http://chinaestone.iteye.com/blog/468138 DirectBuffer及内存泄漏 http://blog.csdn.net/zhouhl_cn/article/d......

mj4738
2012/10/15
0
0
Java FileInputStream

一、序言 IO操作,才程序中比较普遍,JAVA 中提出了IO/NIO 的概念,也一直在说NIO 比IO快,一直不知道原因,就想memcache 和ehcache 比较优劣一样,这些东西得自己看看如何实现的,才 知道区...

pczhangtl
2014/08/03
0
0
111 多线程JUC包下代码分析

Java多线程系列目录(共43篇) AtomicLongFieldUpdater:通过反射+CAS实现对传入对象的指定long字段实现类似AtomicLong的操作 http://www.cnblogs.com/skywang12345/p/javathreadscategory.ht...

素雷
2017/10/31
0
0

没有更多内容

加载失败,请刷新页面

加载更多

颜色模型与颜色应用---光的特性

电磁频谱 颜色的心理学特征

中国龙-扬科
18分钟前
2
0
android音频及强噪相关

Android AudioRecord和AudioTrack介绍(Android音频收集和播放 麦克风降噪) https://blog.csdn.net/tanningzhong/article/details/72844559 音频采集(AudioRecorder) https://www.jianshu.......

whoisliang
25分钟前
2
0
redis-持久化

RDB rdb持久化是把当前进程数据生成快照保存到磁盘的过程。触发RDB持久化过程分为手动触发和自动触发。 触发机制 bgsave执行流程 rdb优缺点 AOF 记录每次写命令,重启时再重新执行aof文件中的...

grace_233
29分钟前
3
0
电话激活Windows 中文操作系统步骤

已购买微软MAK批量授权,系统又在企业内网中,无法通过连接Internet进行激活,还可以通过电话完成激活。 前期准备 请提前准备好产品密钥,Product Key格式如下:XXXXX-XXXXX-XXXXX-XXXXX-XXX...

tonyfox
31分钟前
4
0
Apache用户认证,域名跳转,访问日志

Apache用户认证 当设置了用户认证后,用户访问网站时,需要输入用户名和密码才能访问。 可以全局设置,也可以为某几个虚拟主机单独配置。 下面以全局配置进行操作示例。 编辑httpd.conf进行配...

野雪球
36分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部