黑马程序员——【Java】IO——字节流:复制媒体文件

来源:互联网 发布:mac wine 软件 编辑:程序博客网 时间:2024/06/05 17:25
------- android培训、java培训、期待与您交流! ----------

/*
 
复制一个图片
 思路:
 1,用字节读取流对象和图片关联。
 2,用字节写入流对象创建一个图片文件。用于存储获取到的图片数据。
 3,通过循环读写,完成数据的存储。
 4,关闭资源。
 */
import java.io.*;
class CopyPic {
    public static void main(String[] args) {
        String projectPath = System.getProperty("user.dir");
        FileOutputStream fos = null;
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(projectPath+"/anye.jpg");     //读取
            fos = new FileOutputStream(projectPath+"/anye2.jpg");   //写入
            byte[] buf = new byte[1024];
            int len = 0;
            while ((len = fis.read(buf)) != -1) {
                fos.write(buf, 0, len);
            }
        } catch (IOException e) {
            throw new RuntimeException("复制文件失败");
        } finally {
            try {
                if (fis != null)
                    fis.close();
            } catch (IOException e) {
                throw new RuntimeException("读取关闭失败");
            }
            try {
                if (fos != null)
                    fos.close();
            } catch (IOException e) {
                throw new RuntimeException("写入关闭失败");
            }
        }
    }
}

/*
 演示mp3的复制。通过缓冲区。
 BufferedOutputStream
 BufferedInputStream
    read方法在提升,保证-1的不发生
    write方法则在强转,转为Byte
*/
import java.io.*;
class CopyMp3 {
    public static void main(String[] args) throws IOException {
        long start = System.currentTimeMillis();
        copy_2();
        long end = System.currentTimeMillis();
        System.out.println((end - start) + "毫秒");
    }
    public static void copy_2() throws IOException {
        String projectPath = System.getProperty("user.dir")+"/";
        MyBufferedInputStream bufis = new CopyMp3().new MyBufferedInputStream(
                new FileInputStream(projectPath + "Ending.mp3"));
        BufferedOutputStream bufos = new BufferedOutputStream(
                new FileOutputStream(projectPath + "Ending2.mp3"));
        int by = 0;
        // System.out.println("第一个字节:"+bufis.myRead());
        while ((by = bufis.myRead()) != -1) {
            bufos.write(by);
        }
        bufos.close();
        bufis.myClose();
    }
    // 通过字节流的缓冲区完成复制。
    public static void copy_1() throws IOException {
        String projectPath = System.getProperty("user.dir")+"/";
        BufferedInputStream bufis = new BufferedInputStream(
                new FileInputStream(projectPath + "Ending.mp3"));
        BufferedOutputStream bufos = new BufferedOutputStream(
                new FileOutputStream(projectPath + "Ending2.mp3"));
        int by = 0;
        while ((by = bufis.read()) != -1) {
            bufos.write(by);
        }
        bufos.close();
        bufis.close();
    }
    
    class MyBufferedInputStream {
        private InputStream in;
        private byte[] buf = new byte[1024 * 4];
        private int pos = 0, count = 0;
        MyBufferedInputStream(InputStream in) {
            this.in = in;
        }
        // 一次读一个字节,从缓冲区(字节数组)获取。
        // 当为byte时,若首次取出11111111即为-1
        public int myRead() throws IOException {
            // 通过in对象读取硬盘上数据,并存储buf中。
            if (count == 0) {
                count = in.read(buf);
                if (count < 0)
                    return -1;
                pos = 0;
                byte b = buf[pos];
                count--;
                pos++;
                return b & 255;
            } else if (count > 0) {
                byte b = buf[pos];
                count--;
                pos++;
                return b & 0xff;
            }
            return -1;
        }
        public void myClose() throws IOException {
            in.close();
        }
    }
    /*
     * 11111111-111111110000000000101001001010100101010010101001010
     * 
     * 
     * byte: -1 ---> int : -1; 00000000 00000000 00000000 11111111 255
     * 
     * 11111111 11111111 11111111 11111111
     * 
     * 
     * 11111111 -->
提升了一个int类型 那不还是-1吗?是-1的原因是因为在8个1前面补的是1导致的。
     * 那么我只要在前面补0,即可以保留原字节数据不变,又可以避免-1的出现。 怎么补0呢?
     * 
     * 11111111 11111111 11111111 11111111 &00000000 00000000 00000000 11111111
     * ------------------------------------ 00000000 00000000 00000000 11111111
     * 
     * 0000-0001 1111-1110 000000001 1111-1111 -1
     * 
     * 
     
* 结论: 字节流的读一个字节的read方法为什么返回值类型不是byte,而是int。
     * 因为有可能会读到连续8个二进制1的情况,8个二进制1对应的十进制是-1.
     * 那么就会数据还没有读完,就结束的情况。因为我们判断读取结束是通过结尾标记-1来确定的。 所以,为了避免这种情况将读到的字节进行int类型的提升。
     * 并在保留原字节数据的情况前面了补了24个0,变成了int类型的数值。
     * 
     * 
     * 而在写入数据时,只写该int类型数据的最低8位。
     */

}

总结自黑马程序员毕向东老师课堂笔记。DEMO可运行。int写入仅有末八位

0 0
原创粉丝点击