IO 之 mark()、reset()

package com.shob.io;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class OIClazz {

	public static void main(String[] args) throws IOException {
		writeToFile();
		readFromFile();
	}

	public static void ttt() {      
	     
        try {      
            // 初始化一个字节数组,内有5个字节的数据      
            byte[] bytes={1,2,3,4,5};      
            // 用一个ByteArrayInputStream来读取这个字节数组      
            ByteArrayInputStream in=new ByteArrayInputStream(bytes);      
            // 将ByteArrayInputStream包含在一个BufferedInputStream,并初始化缓冲区大小为2。      
            BufferedInputStream bis=new BufferedInputStream(in,2);       
            // 读取字节1      
            System.out.print(bis.read()+",");      
            // 在字节2处做标记,同时设置readlimit参数为1      
            // 根据JAVA文档mark以后最多只能读取1个字节,否则mark标记失效,但实际运行结果不是这样      
            System.out.println("mark");      
            bis.mark(1);      
                  
            /*   
             * 连续读取两个字节,超过了readlimit的大小,mark标记仍有效   
             */     
            // 连续读取两个字节      
            System.out.print(bis.read()+",");       
            System.out.print(bis.read()+",");       
            // 调用reset方法,未发生异常,说明mark标记仍有效。      
            // 因为,虽然readlimit参数为1,但是这个BufferedInputStream类的缓冲区大小为2,      
            // 所以允许读取2字节      
            System.out.println("reset");      
            bis.reset();      
                  
            /*   
             * 连续读取3个字节,超过了缓冲区大小,mark标记失效。   
             * 在这个例子中BufferedInputStream类的缓冲区大小大于readlimit,   
             * mark标记由缓冲区大小决定   
             */     
            // reset重置后连续读取3个字节,超过了BufferedInputStream类的缓冲区大小      
            System.out.print(bis.read()+",");      
            System.out.print(bis.read()+",");      
            System.out.print(bis.read()+",");      
            // 再次调用reset重置,抛出异常,说明mark后读取3个字节,mark标记失效      
            System.out.println("reset again");      
            bis.reset();      
        } catch (IOException e) {      
            // TODO Auto-generated catch block      
            e.printStackTrace();      
        }      
    }      
	/**
	 * BufferedInputStream类调用mark(int readlimit)方法后读取多少字节标记才失效,
	 * 是取readlimit和BufferedInputStream类的缓冲区大小两者中的最大值,而并非完全由readlimit确定。
	 * 这个在JAVA文档中是没有提到的。
	 */
	private static void readFromFile() {
		InputStream inputStream = null;
		try {
			inputStream = new BufferedInputStream(new FileInputStream(new File("test.txt")),1);
			// 判断该输入流是否支持mark操作
			if (!inputStream.markSupported()) {
				System.out.println("mark/reset not supported!");
				return;
			}
			int ch;
			int count = 0;
			boolean marked = false;
			while ((ch = inputStream.read()) != -1) {
				System.out.print("." + ch);
				if ((ch == 4) && !marked) {
					// 在4的地方标记位置 
					//如果2个都是1,在mark位置往下读取1个字节,在读取下一个字节,也就是第二个的时候mark失效,这时候reset会出错,因为无法读取到mark标志,mark已失效
					//如果一个为1一个为3,最多允许往下读取3个字节,在读取第四个的时候,mark已失效,就无法reset到正确的mark标志
					inputStream.mark(1);
					marked = true;
				}
				if (ch == 6 && count < 2) {
					// 重设位置到4
					inputStream.reset();
					count++;
				}
			}
			System.out.println(count);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				inputStream.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	private static void writeToFile() {
		OutputStream output = null;
		try {
			output = new BufferedOutputStream(new FileOutputStream(new File("test.txt")));
			byte[] b = new byte[20];
			for (int i = 0; i < 20; i++)
				b[i] = (byte) i;
			// 写入从0到19的20个字节到文件中
			output.write(b);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				output.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

  

posted @ 2017-02-14 10:51  斌灬小生不才  阅读(266)  评论(0编辑  收藏  举报