字节流----图片、媒体的操作

  • InputStream:读;
  • OutputStream:写;
  • 字符流使用的是字符数组,字节流使用的是字节数组;
  • MyBufferedInputStream
    • 定义数组
    • 定义指针
    • 定义计数器
    • mp3格式文件开头就有-1的二进制位,
    • byte类型的-1提升为int类型的-1,原因是因为在8个1前面补1导致的;如果补0就可以解决这个问题。接受为什么用int不用byte, 在8个1前面补0,不补1;方法:让它与255与运算就OK!
    • 读的时候类型提升了,但是写入的时候只写低八位,保证了元数据的原样性。

而其他正常byte类型的数据提升后的值与255进行按位与操作后的数值不变,这就是与255按位与操作的魅力。

在计算机中数据的存储使用补码表示的,-1的补码就是8个1或者32个1。

那问题来了,如果reader方法读到了行尾的-1怎么办,是返回-1还是返回255。


代码如下:

import java.io.*;
//创建自己的缓存器,用来缓存字节流。
class MyBufferedInputStream1{
     //创建一个字节流对象;
     private InputStream is;
     private byte[] buf = new byte[1024*4];
     private int pos, count;
     MyBufferedInputStream1(InputStream it){
           this.is = it;
     }
     //一次从缓冲区读取一个字节;
     //为什么不返回byte类型呢?
     //为解决开头读到八个1时,返回-1的情况;对字节进行提升,
     //在前面补上0,这样就能保证数值没有变化,又能防止返回-1;
     //为了在前面补0,我们就让byte类型的数据提升后和255进行按位与操作即可。
     public int myRead() throws IOException{
           //通过is对象读取硬盘上的数据,并存到buf中。
           if(count==0) {
                count = is.read(buf);
                if(count<0)
                     //当缓存器中的字符串长度小于0时,返回-1。
                     return -1;
                pos = 0;  //如果刚好count=0,就给缓存器中的字符串附上下标。
                byte b = buf[pos];  //读取一个字符
                //往后面移1位,字符数量-1
                count--;
                pos++;
                //返回int类型
                return b&0xffff;
           }
           //如果count>0,就重复上述取值的过程。
           else if(count>0) {
                byte b = buf[pos];
               count--;
                pos++;
                return b&0xffff;
           }
           return -1;
     }
     //模仿官方缓存器,写一个自己的关闭文件的快捷方法;
     public void myClose()throws IOException{
           is.close();
     }
}
public class MyBufferedInputStream {
     public static void main(String[] args) {
           //调用系统中返回当前时间的函数,用来计算拷贝文件需要多长时间。
           long start = System.currentTimeMillis();
           try {
               copy_2();
           }
           catch(Exception e) 
                System.out.println("拷贝失败!");
           }
           long end = System.currentTimeMillis();
           System.out.println((end-start)+"ms");
     }
     //异常处理时,代码量很多要学会用静态函数。
     public static void copy_2() throws IOException{
          MyBufferedInputStream1 mbis = 
new MyBufferedInputStream1(new FileInputStream("[F://MOVE_MUSIC//1.mp3](file:///F://MOVE_MUSIC//1.mp3)"));
           //由于只写了自己的输入字节流缓存器,输出字节流缓存器就都用Java自己的。
           BufferedOutputStream bfos = 
new BufferedOutputStream(new FileOutputStream("[F://MOVE_MUSIC//2.mp3](file:///F://MOVE_MUSIC//2.mp3)"));
           System.out.println("第一个字节:"+mbis.myRead());
           int by = 0;
           //虽然有缓存器,但缓存器其实就是字节流对象的装饰类,还是每次只能读取一位;
           //要想一行一行的读写数据,还是要用while循环实现。
           while((by=mbis.myRead())!= -1) {
                bfos.write(by);
           }
           mbis.myClose();
           bfos.close();
     }
}

你可能感兴趣的:(字节流----图片、媒体的操作)