过滤流:
IO流按功能分类可以分为节点流和过滤流,节点流是用来直接操作目标设备的流,比如我们前面介绍的FileReader、FileWriter、FileInputStream、FileOutputStream,而过滤流是对应已存在的流进行包装,以提供更强大和灵活的读写功能。
转换流:
将字节流和字符流进行相互转换的高级流:
InputStreamReader :将字节输入流转换为字符输入流
OutputStreamWriter:将字节输出流转换成字符输出流
public class OutputStreamWriter extends Writer
public OutputStreamWriter(OutputStream out) {
super(out);
try {
//设定编码的过程
se = StreamEncoder.forOutputStreamWriter(out, this, (String)null);
} catch (UnsupportedEncodingException e) {
throw new Error(e);
}
}
通过研究FileReader的实现
public class FileReader extends InputStreamReader {
public FileReader(String fileName) throws FileNotFoundException {
super(new FileInputStream(fileName));
}
FileReader实现是继承自InputStreamReader转换流,转换流的构造使用到FileInputStream字节输入流,FileReader的实现是将读取到的字节流通过转换流(本质是通过编码器将字节按照对应的编码表:ASCII、GBK、UTF-8)将其解析为我们能够识别的文本内容
缓冲流:
提高IO的读取速度
字节缓冲流:BufferInputStream、BufferOutputStream
字符缓冲流:BufferReader、BufferWriter
public BufferedReader(Reader in, int sz) {//需要传入一个Reader对象,sz是缓冲容量默认为:defaultCharBufferSize = 8192;
super(in);
if (sz <= 0)
throw new IllegalArgumentException("Buffer size <= 0");
this.in = in;
cb = new char[sz];
nextChar = nChars = 0;
}
特有方法:
BufferWriter
void newLine() throws IOException ;根据当前系统,写入一个换行符
BufferReader
String readLine() throws IOException //读取文本中一行内容
RandomAccessFile:
RandomAccessFile既可以读取文件内容,也可以向文件输出数据。同时,RandomAccessFile支持“随机访问”的方式,程序也可以直接跳转到文件的任意地方来读写数据。
RandomAccessFile的构造函数
mode:指定RandomAccessFile的访问模式,一共有4种模式。
**"r" : ** 以只读方式打开。调用结果对象的任何 write 方法都将导致抛出 IOException。
"rw": 打开以便读取和写入。
"rws": 打开以便读取和写入。相对于 "rw","rws" 还要求对“文件的内容”或“元数据”的每个更新都同步写入到基础存储设备。
"rwd" : 打开以便读取和写入,相对于 "rw","rwd" 还要求对“文件的内容”的每个更新都同步写入到基础存储设备。
public RandomAccessFile(String name, String mode)
throws FileNotFoundException
{
this(name != null ? new File(name) : null, mode);
}
public RandomAccessFile(File file, String mode)
throws FileNotFoundException//抛出IO异常
{
this(file, mode, false);
}
private RandomAccessFile(File file, String mode, boolean openAndDelete)
throws FileNotFoundException
{
String name = (file != null ? file.getPath() : null);
int imode = -1;
if (mode.equals("r"))
imode = O_RDONLY;
else if (mode.startsWith("rw")) {
imode = O_RDWR;
rw = true;
if (mode.length() > 2) {
if (mode.equals("rws"))
imode |= O_SYNC;
else if (mode.equals("rwd"))
imode |= O_DSYNC;
else
imode = -1;
}
}
if (openAndDelete)
imode |= O_TEMPORARY;
if (imode < 0)
throw new IllegalArgumentException("Illegal mode \"" + mode
+ "\" must be one of "
+ "\"r\", \"rw\", \"rws\","
+ " or \"rwd\"");
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(name);
if (rw) {
security.checkWrite(name);
}
}
if (name == null) {
throw new NullPointerException();
}
if (file.isInvalid()) {
throw new FileNotFoundException("Invalid file path");
}
fd = new FileDescriptor();
fd.attach(this);
path = name;
open(name, imode);
FileCleanable.register(fd); // open sets the fd, register the cleanup
}
RandomAccessFile的特有方法:
long getFilePointer( ):返回文件记录指针的当前位置
void seek(long pos ):将文件指针定位到pos位置
RandomAccessFile练习:
在指定文件的指定位置插入指定数据:
public static void indexAdd(String puth,Long index,String date) throws IOException {
File file = new File(puth);
if(!file.exists()){
throw new IOException();
}
RandomAccessFile accessFile = null;
FileOutputStream stream =null;
FileInputStream stream1 = null;
try {
accessFile = new RandomAccessFile(file,"rw");
accessFile.seek(index);
stream = new FileOutputStream(file.getParent()+ File.separator + "tmp.txt",true);
byte[] bytes = new byte[100];
int i ;
while ((i=accessFile.read(bytes))!= -1){
stream.write(bytes,0,i);
}
accessFile.seek(index);
accessFile.writeUTF(date);
stream1 = new FileInputStream(file.getParent() + File.separator + "tmp.txt");
while ((i=stream1.read(bytes))!= -1){
accessFile.write(bytes,0,i);
}
new File(file.getParent() + File.separator + "tmp.txt").deleteOnExit();
}catch (Exception e){
e.printStackTrace();
}finally {
if (accessFile !=null) accessFile.close();
if (stream!=null) stream.close();
if (stream1!=null) stream1.close();
}
}