IO阶段小结

IO:
	字节流:
		针对的字节数据,包括文本也包括媒体数据,如果是纯文本用字符流处理较为便捷。
		字节流所使用的缓冲区是一个byte[]。
	常用的对象:
		FileInputStream,FileOutputStream,BufferedInputStream,BufferedOutputStream。
	需求:
		copyMp3

		public void copyMp3()
		{
			FileInputStream fis = new FileInputStream("1.mp3");
			BufferedInputStream bufis = new BufferedInputStream(fis);

			FileOutputStream fos = new FileOutputStream("2.mp3");
			BufferedOutputStream bufos = new BufferedOutputStream(fos);

			int by = 0;

			while((by=bufis.read())!=-1)
			{
				bufos.write(by);
				bufos.flush();
			}
			
			bufos.close();
			bufis.close();

		}
		
	模拟BufferedInputStream。原理:其实将一个字节数组进行封装,通过方法将一批数据存入数组中,在通过数组的指针每一次返回数组中一个字节。当数组元素全部取出后,在存入一批新的数据,重复此过程。

	class MyBufferedInputStream
	{
		private InputStream in;
		private byte[] arr = new byte[1024*4];
		private int pos = 0,count = 0;
		MyBufferedInputStream(InputStream in)
		{
			this.in = in ;
		}

		public int myRead()throws IOException
		{
			if(count==0)
			{
				count = in.read(arr);
				if(count<0)
					return -1;
				pos = 0;
				byte b = arr[pos];
				pos++;
				count--;
				return b;//return b&255;
			}
			else if(count>0)
			{
				byte b = arr[pos];
				pos++;
				count--;
				return b;//return b&0xff;
			}
			return -1;
		}
		public void myClose()throws IOException
		{
			in.close();
		}
	}

	当使用自定义的缓冲区时,居然出现的秒杀的情况,为什么会如此呢?
	因为mp3数据最终的二进制表现形式中,很容易出现连续N多1的情况,
	只要出现了连续的8个1,对于一个字节而言十进制体现形式就是-1。
	那么就满足while循环结束条件。程序终止。
	为了避免这种情况,在读到一个字节时,将该字节进行了提升变成int型。
	但是byte-1,变成int 还是-1。为了避免,在进行提升的过程中,保留的源字节的8为数据,并在前以补零方式进行提升。

	这样一个byte -1 变成了int 的255。这就避免了-1的情况。
	如何补的零呢?只要将读到的字节&255或者&0xFF.都可以。这也是read方法不是返回byte而返回int类型的原因。

	通过该过程就可以明确,read方法在对字节或者字符进行提升,而write方法在对提升后的int数据进行强转,
	只写出了最低的8位,或者最低的16位。

---------------------------------

字符流:
四个:

字节流:
四个。

为了实现字符和字节流之间的转换,出现了转换流。

转换流的由来,
当读到的字节数据都是纯文本的时候,而且文本中出现中文字符,那么在解析该字节数据时就需要指定编码表。
因为可以识别中的编码表不唯一。在使用转换流时,如果未指定编码表,那么默认使用本地码表。

InputStramReader:字节通向字符的桥梁
OutputStreamWriter:字符通向字节的桥梁



--------------------------------

流操作的基本规律:
1,明确数据源和数据目的。
	明确到底是使用输入流还是输出流。
2,明确要处理的数据是否是纯文本。
	明确到底是使用字符流还是字节流。
当明确体系后,到底该用该体系的哪个对象呢?
根据数据存在的设备而定,
数据源所在设备可以是,硬盘,键盘,内存。
数据目的所在设备可以是,硬盘,控制台,内存。

需求:
获取键盘录入,将录入信息存储到本地文件中。

	源:键盘录入,输入流。
	处理的数据:纯文本,字符输入流。Reader
	该用哪个对象呢?
	键盘录入System.in完成的。那么它是一个标准的字节输入流。InputStream。

	为了操作文本数据方便,将字节流转换成字符流。使用InputStreamReader。
	但是为了提高对字符操作的效率,BufferedReader.

	BufferedReader bufr = 
		new BufferedReader(new InputStreamReader(System.in));

	目的:本地文件(硬盘)输出流。
	处理的数据:纯文本,字符输出流。Writer。
	该用该体系的哪个对象呢?
		可以操作的文件FileWriter对象。
		为了提高写入流的效率。BufferedWriter.
		
	
	public void show()
	{
		BufferedReader bufr = 
			new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bufw = 
			new BufferedWriter(new FileWriter("a.txt"));

		String line = null;
		while((line=bufr.readLine())!=null)
		{
			if("over".equals(line))
			break;
			bufw.write(line);
			bufw.newLine();
			bufw.flush();
		}
		bufw.close();
		bufr.close();

	}
	/*
	如果基本上面的分析,但不使用缓冲区,代码是一个什么样子呢?
	*/
	public static void show()throws IOException
	{
		InputStreamReader isr = new InputStreamReader(System.in);

		FileWriter fw = new FileWriter("a.txt");

		char[] arr = new char[1024];

		int len = 0;

		while((len=isr.read(arr))!=-1)
		{
			System.out.println(len);
			String s = new String(arr,0,len-2);
			if("over".equals(s))
				break;
			fw.write(arr,0,len);
			fw.flush();
		}
		fw.close();
		isr.close();
	}


获取本地文本数据,将数据息存储到本地另一个文件中,按照UTF-8的编码形式。

源:硬盘,输入流。
数据:纯文本,字符输入流,Read。
该用哪个对象呢?
因为是文件FileReader为了提高效率BufferedReader.

目的:本地文件(硬盘)输出流。
	处理的数据:纯文本,字符输出流。Writer。
	该用该体系的哪个对象呢?
		可以操作的文件的对象,但是因为要将字符数据进行编码在进行存储,就需要使用字符向字节过滤的桥梁。OutputStreamWriter.
		就要使用转换流。而转换流要接收的对象都是字节流对象。所以要使用的可以操作的File的FileOutputStream。
		为了提高写入流的效率。BufferedWriter.

	public void show()
	{
		BufferedReader bufr = new BufferedReader(new FileReader("a.txt));

		BufferedWriter bufw = 
			new BufferedWriter(new OutputStreamWriter(new FileOutputStream("b.txt"),"UTF-8"));
	}


-----------------------------

异常日志。
printStackTrace(PrintStream );

try
{
	int[] arr = new int[2];
	System.out.println(arr[3]);
}
catch(Exception e)
{
	Date d = new Date();
	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	String time = sdf.format(d);
	
	try 
	{
		PrintStream out = new PrintStream("exception.log");
		e.printStackTrace(out);

		out.close();
	}
	catch(IOException e)
	{
		throw new RuntimeException("日志建立失败");
	}
	
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值