字节流
操作图片数据就要用到字节流。
字符流使用的是字符数组char[],字节流使用的是字节数组byte[]。
字节流读写文件
针对文件的读写,JDK专门提供了两个类,分别是FileInputStream和FileOutputStream。
FileInputStream是InputStream的子类,它是操作文件的字节输入流,专门用于读取文件中的数据
FileOutputStream,它是OutputStream的子类,专门用于读取文件中的数据
如果是通过FileOutputStream向一个已经存在的文件中写入数据,那么该文件中的数据首先会被清空,再写入新的数据。
若希望在存在的文件内容之后追加新内容,则可使用FileOutputStream的构造函数FileOutputStream(String fileName, boolean append)来创建文件输出流对象,并把append 参数的值设置为true
FileInputStream 读
FileOutputstream 写
读取
FileInputStream fis=new FileInputStream ("a.txt");
byte[] buf=new byte[fis].available(0)]; //定义一个刚刚好的缓冲区,不用再循环了
fis.read(buf);
System.out.println(new String(buf));
fis.close();
字节文件输入流FIleInputStream
该类的构造方法
FileInputStream(File file) 通过file对象创建类
FileInputStream(FileDescriptor fdObj) 参数fdObj为文件描述符,通过文件描述符创建类
FileInputStream(String name) 参数name为文件路径名,通过文件路径创建类
方法
int available() 返回可以从该文件输入流中读取的字节数
void close()
关闭文件输入流,同时释放系统资源
protected void finalize() 确认文件输入流不在被引用的状态,并可以调用close方法
java.io.channels.FileChannel getChannel() 返回与该文件输入流有关的FileChannel对象
FileDescriptor getFD() 返回连接到文件系统(正被该FileInputStream使用)中实际文件的FileDescriptor对象
int read() 从该输入流中读取一个数据字节,并以int类型返回
int read(byte[] b) 读取输入流中b.length个字节的数据,并存入字节数组b中
int read(byte[] b, int off, int len) 读取输入流中从偏移量off开始的len个字节的数据,并存入字节数组b中
long skip(long n) 跳过输入流中的数据,同时丢弃n个字节的数据
字节文件输出流FileOutputStream
构造方法
FileOutputStream(File file) 通过file对象创建FileOutputSteam
FileOutputStream(File file, boolean append) 通过file对象创建类,append为true或false表示是否在文件末尾追加
FileOutputStream(FileDescriptor fdObj) 参数fdObj为文件描述符,通过文件描述符创建FileOutputStream
FileOutputStream(String name) 参数name为文件路径名,通过文件路径创建FileOutputStream
FileOutputStream(String name, boolean append) 参数name为文件路径名,通过文件路径创建FileOutputStream, append为true或false表示是否在文件末尾追加
方法
void close() 关闭该文件输出流,同时释放系统资源
protected void finalize() 断开到文件的连接,确认该文件输出流不处在被引用状态,并可以调用close方法
FileDescriptor getFD() 返回与该流有关的文件描述符FileDescriptor对象
void write(byte[] b) 将b.length个字节的数据从指定字节数组写入到该文件输出流中
void write(byte[] b, int off, int len)
将指定字节数组中的部分数据(从偏移量off开始的len个字节)写入到该文件输出流
void write(int b) 将指定字节b写入到该文件输出流
输入流过滤器FilterInputStream
过滤流提供了在读写数据的同时可以对数据进行处理的功能,同时还提供了同步机制,使得某一时刻只有一个线程可以访问一个数据流,以防止多个线程同时对一个数据流进行操作所带来的意想不到的结果。
为了使用一个过滤流,必须首先把过滤流连接到某个输入输出流上,通常通过在构造方法的参数中指定所要连接的输入输出流来实现。
构造方法
FilterInputStream(InputStream in); 指定InputStream输入流
方法
public int available() 该方法用于返回可以该输入流中读取的字节数
public void close() 该方法用于关闭输入流,并释放系统资源
public void mark(int readlimit) 该方法用于标记输入流中的当前位置
public boolean markSupported() 该方法用于测试该输入流是否支持mark和reset方法
public int read()
该方法用于从输入流中读取一个数据字节
public int read(byte[] b) 该方法用于从输入流中读取byte.length个字节的数据并存入到一个字节数组b中
public int read(byte[] b,int off,int len) 该方法用于从输入流中读取从偏移量off开始len个字节的数据并存入到一个字节数组b中
public void reset() 该方法用于将流重新定位到对该输入流最后一次调用mark方法时的位置
public long skip(long n) 该方法用于跳过输入流中n个字节的数据,并丢弃
文件的拷贝
文件的拷贝就需要通过输入流来读取文件中的数据,通过输出流将数据写入文件。
练习:复制图片
FileOutputStream fw=null;
FileInputStream fr=null;
try {
fos=new FileOutputStream("b.jpg");
fis=new FileInputStream("a.jpg");
byte[] buf=new byte[1024];
int num=0;
while ((num=fis.read(buf))!=-1) {
fis.write(buf,0,num);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(fis!=null)
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
字节流的缓冲区
在IO包中提供两个带缓冲的字节流,分别是BufferedInputStream和BufferdOutputStream,这两个流都使用了装饰设计模式。它们的构造方法中分别接收InputStream和OutputStream类型的参数作为被包装对象,在读写数据时提供缓冲功能。
为了提高效率也可以定义一个字节数组作为缓冲去。在拷贝文件时,可以一次性读取多个字节的数据,并保存在字节数组中,然后将字节数组中的数据一次性写入文件
字节缓冲区输入流BufferedInputStream
是InputStream类的间接子类,其直接父类是FilterInputStream。
构造方法
BufferedInputStream(InputStream in) 以InputStream对象in为参数创建类
BufferedInputStream(InputStream in, int size) 以InputStream对象in为参数创建类,并且通过参数size指定缓存区大小
方法
public int available() 该方法用于返回还可以从输入流中读取的字节数
public void close() 该方法用于关闭输入流,并释放系统资源
public void mark(int readlimit) 该方法用于标记输入流中的当前位置
public boolean markSupported() 该方法用于测试输入流是否支持mark和reset方法
public int read() 该方法用于从输入流中读取下一个数据字节
public int read(byte[] b,int off,int len) 读取字节输入流中的从偏移量off开始的len个字节并存入到指定的byte数组b中
public void reset() 将此流重新定位到最后一次调用mark方法时所处的位置
public long skip(long n) 跳过并且放弃输入流中的n个字节数据
字节缓冲区输出流BufferedOutputStream
是OutputStream类的间接子类,其直接父类是FilterOutputStream。
构造方法
BufferedOutputStream(OutputStream out) 以InputStream对象in为参数创建类
BufferedOutputStream(OutputStream out, int size) 以OutputStream对象out为参数创建类,并且通过size指定缓存区大小
方法
public void flush() 该方法用于刷新输出流
public void write(byte[] b,int off,int len) 将字节数组中从偏移量off开始的len个字节写入到输出流
public void write(int b) 将指定的字节b写入到输出流
flush()方法用于强制将缓冲区的内容立即写入输出流。在使用缓存区机制的输出流时,调用write()方法后数据并没有立即写入输出流,而是先放到缓存区中。所以,在必要的地方可以调用flush()方法强制刷新缓冲区。
InputStream类的方法
public abstract int read() 从输入流读取下一个数据字节。如果因已到达流末尾而没有可用的字节,则返回值-1
public int available() 以不受阻塞地从输入流中读取字节。该方法返回读取字节数
public void mark(int readlimit) 在此输入流中标记当前的位置
public boolean markSupported() 判断输入流是否支持mark()和reset()方法。如果支持则返回true。
public int read(byte[] b) 从输入流中读取一定数量的字节并将其存储在缓冲区数组b中。该方法返回读入缓冲区的总字节数
public int read(byte[] b,int off,int len) 从off处开始读取流中len长度的字节并将其存储在数组b中。返回读取到的字节数
public void reset() 将此流重新定位到输入流最后调用mark方法时的位置
public long skip(long n) 跳过此输入流中的n个字节。参数n表示要跳过的字节数。该方法返回实际跳过的字节数
public void close() 关闭输入流
OutputStream类的方法
public void writer (byte[] b) 将字节数组写入输出流
public void writer (byte[] b, int off, int len) 将指定字节数组b中以off开始的len个字节写入输出流
public void flush() 刷新输出流
public void close() 关闭输出流
装饰设计模式
当想要对已有的独享进行功能增强时,可以定义类,将已有的对象传入,基于已经有的功能,并提供加强功能,那么自定义的该类称为装饰类
装饰类通常会通过构造方法接收被装饰的对象,并基于被装饰的对象的功能,提供更强的功能。
已知类:
Person() {
public void chifan() {
}
}
增强类:
superPerson() {
private Person p;
superPerson(Person p) {
this.p=p;
}
public void superchifan() {
p.chifan();
.........
{
}
自定义装饰类
package com.io;
import java.io.*;
public class MyBufferedReader {
private Reader r;
public MyBufferedReader(Reader r) {
super();
this.r = r;
}
//可以一次读取一行的方法
public String myReadLine() throws IOException {
//定义一个临时容器。StringBulider容器,应用于存储字符数组
StringBuilder sb=new StringBuilder();
int ch=0;
while((ch=r.read())!=-1) {
if(ch=='\r')
continue;
if(ch=='\n')
return sb.toString();
else
sb.append((char)ch);
}
if(sb.length()!=0)
return sb.toString();
return null;
}
//复写reader中的抽象方法
//复写close方法
public void close() throws IOException {
r.close();
}
//复写read方法
public int read (char[] c,int off,int len) throws IOException {
return r.read(c, off, len);
}
}
装饰设计模式就是通过包装一个类,动态地为它增加功能的一种设计模式。