IO阶段小结
IO:字节流:针对的字节数据,包括文本也包括媒体数据,如果是纯文本用字符流处理较为便捷。字节流所使用的缓冲区是一个byte[]。常用的对象:FileInputStream,FileOutputStream,BufferedInputStream,BufferedOutputStream。需求:copyMp3public 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("日志建立失败");}}?