Java的IO流是实现输入/输出的基础,它可以方便的实现数据的输入/输出操作。
Java中把不同的输入/输出源(键盘、文件、网络连接等)抽象为“流”(stream),通过流的方式可以使用相同的方式来访问不同的输入/输出源。
stream是从起源(source)到接收(sink)的有序数据。
再java.io包中,大概分为以下四种:
- 基于字节:InputStream、OutputStream
- 基于字符:Write、Reader
- 基于磁盘操作:File
- 基于网络传输:Socket
输入流:只能从中读取数据。
输出流:只能向其写入数据。
文件的编码
gbk编码:中文占用2个字节,英文占用1个字节。
utf-8编码:中文占用3个字节,英文占用1个字节。
utf-16be编码:中文占用2个字节,英文占用2个字节。
Java是双字节编码,utf-16be。
1、字节流
输入流基本方法
int read()
int read(byte[] buf)
int read(byte[] buf, int start, int size)
read()
返回 -1 就表示读到结尾。
int available() // 返回当前可读取的输入字节数
void mark(int numBytes) // 在输入流的当前点放置标记,在读取numBytes个字节之前保持有效
boolean markSupported() // 判断此输入流是否支持 mark() 操作
void reset() // 将输入指针重新改为原来设置的标记
long skip(long numBytes) // 忽略(即跳过)numBytes个输入字节,返回实际忽略的字节数
void close() // 关闭输入流
输出流基本方法
void write(int b) // 写出一个byte到流
void write(byte[] buf)
void write(byte[] buf, int start, int size)
void flush()
void close()
2、字符流
int read()
int read(char[] cbuf)
int read(char[] cbuf, int off, int len)
read()
返回 -1 就表示读到结尾。
void mark(int numBytes) // 在输入流的当前点放置标记,在读取numBytes个字符之前保持有效
boolean markSupported() // 判断此输入流是否支持 mark() 操作
void reset() // 将输入指针重新改为原来设置的标记
long skip(long numBytes) // 忽略(即跳过)numBytes个输入字符,返回实际忽略的字符数
boolean ready() // 如果下一个输入请求不等待就返回 true,否则返回 false
void close() // 关闭输入流
void write(int c)
void write(char[] cbuf)
void write(char[] cbuf, int off, int len)
void write(String str)
void write(String str, int off, int len)
Writer append(char ch)
Writer append(CharSequence chars)
Writer append(CharSequence chars, int begin, int end)
void flush()
void close()
3、 处理字节或二进制对象(图片、视屏等媒体文件):
FileInputStream 具体实现了在文件上读取数据
FileOutputStream 实现了向文件中写出byte数据的方法
4、读写二进制数据
DataOutputStream
、DataInputStream
是对"流"功能的扩展,可以更加方便的读取int
、long
、short
、float
、double
、char
、byte
、boolean
类型数据。
DataInputStream
int readInt()
double readDouble()
long readLong()
short readShort()
float readFloat()
char readChar()
byte readByte()
boolean readBoolean()
DataOutputStream
writeInt(int val)
writeDouble(double val)
writeLong(long val)
writeShort(short val)
writeFloat(float val)
writeChar(char val)
writeByte(byte val)
writeBoolean(boolean val)
5、带缓存的流:
BufferedInputStream
BufferedOutputStream
BufferedReader
BufferedWriter
增加缓冲功能后,要使用 flush()
才可以将缓冲区的数据写入实际的物理节点。
这四个流类为IO提供了带缓冲区的操作,一般打开文件进行写入 或读取操作时,都会加上缓冲,这种流模式提高了IO的性能。
从应用程序中把输入放入文件,相当于将一缸水倒入到另一个缸中:
FileOutputStream--->write()方法相当于一滴一滴地把水“转移”过去
DataOutputStream-->writeXxx()方法会方便一些,相当于一瓢一瓢把水“转移”过去
BufferedOutputStream--->write方法更方便,相当于一飘一瓢先放入桶中,再从桶中倒入到另一个缸中,性能提高了
6、转换流
InputStreamReader
将字节输入流转换成字符输入流
OutputStreamWriter
将字节输出流转换成字符输出流
7、推回输入流
PushbackInputStream
、PushbackReader
void unread(byte[]/char[] buf)
void unread(byte[]/char[] b, int off, int len)
void unread(int b)
8、重定向标准输入输出流
Java的标准输入/输出流分别通过System.in
和System.out
来代表。
在 System 类里,提供了三个重定向标准输入/输出的方法:
static void setErr(PrintStream err)
static void setIn(PrintStream in)
static void setOut(PrintStream out)
RandomAccessFile类 (随机访问文件)
RandomAccessFile
可以自由的访问文件的任意位置,支持“随机访问”的方式。
该类仅限于操作文件,不能访问其他IO设备,如网络、内存映像等。
RandomAccessFile(String filename, String access)
access :文件的访问类型。r
、rw
、rws
、rwd
int read()
void write()
long getFilePointer() // 返回文件记录指针的当前位置
void seek(long pos) // 将文件记录指针定位到 pos 位置
RandomAccessFile 不能向文件的指定位置插入内容,如果直接文件记录指针移动到中间某位置后开始输入,则新输出的内容会覆盖文件中原有的内容。
如果需要向指定位置插入内容,需要先把插入点后面的内容输入缓冲区,等把需要插入的数据写入文件后,再将缓冲区的内容追加到文件后面。
Console类
JDK6添加的类,用来从控制台读写。
Console对象通过System.console()
获得。
readLine()
printf()
readPassword() // 读取密码,不回显键盘的输入
自动关闭资源的 try 语句
在不需要资源时,显式地调用了close()
来关闭资源。代码中广泛的使用这种方法。
JDK7 开始,Java新增了一种功能,自动化关闭资源。这种功能的基础是一种新形式的 try 语句,叫做 try-with-resources
,有时候称为自动资源管理。
try-with-resources
的主要优势在于避免了当不需要资源时,忘记关闭资源的情况。
忘记关闭资源可能会导致内存泄露,并引起其他问题。
为了保证 try 语句可以正常关闭资源,这些资源实现类必须实现 AutoCloseable 或 Closeable 接口,实现这两个接口就必须实现 close() 方法。
其语法形式:
// 声明、初始化了两个可关闭的资源,try语句会自动关闭这两个资源
try (BufferedReader br = new BufferedReader(new FileReader("Test.java"));
PrintStream ps = new PrintStream(new FileOutputStream("a.txt"))) {
System.out.println(br.readLine());
ps.println("输出内容");
}
try 语句块可管理多个资源,用;
隔开。
自动关闭资源的 try 语句后也可以带多个 catch 块和一个 finally 块。
Java7 几乎把所有的“资源类”(包括文件IO的各种类、JDBC编程的类、网络链接等)进行了改写,改写后资源类都实现了 AutoCloseable 或 Closeable 接口。
网友评论