• java学习笔记 --- IO(2)


    IO流的分类:
         流向:
           输入流   读取数据
           输出流   写出数据
         数据类型:
          字节流
              字节输入流   读取数据 InputStream
              字节输出流   写出数据 OutputStream
          字符流
              字符输入流   读取数据 Reader
              字符输出流   写出数据 Writer

     注意:一般我们在探讨IO流的时候,如果没有明确说明按哪种分类来说,默认情况下是按照数据类型来分的。

    1、FileOutputStream:字节输出流

        FileOutputStream的构造方法:
            FileOutputStream(File file)
            FileOutputStream(String name)
        
        字节输出流操作步骤:
          A:创建字节输出流对象
          B:写数据
          C:释放资源

    public class FileOutputStreamDemo {
        public static void main(String[] args) throws IOException {
            // 创建字节输出流对象
            // FileOutputStream(File file)
            // File file = new File("fos.txt");
            // FileOutputStream fos = new FileOutputStream(file);
            // FileOutputStream(String name)
            FileOutputStream fos = new FileOutputStream("fos.txt");
            /*
             * 创建字节输出流对象了做了几件事情:
             * A:调用系统功能去创建文件
             * B:创建fos对象
             * C:把fos对象指向这个文件
             */
            
            //写数据
            fos.write("hello,IO".getBytes());
            fos.write("java".getBytes());
            
            //释放资源
            //关闭此文件输出流并释放与此流有关的所有系统资源。
            fos.close();
            /*
             * 为什么一定要close()呢?
             * A:让流对象变成垃圾,这样就可以被垃圾回收器回收了
             * B:通知系统去释放跟该文件相关的资源
             */
            //java.io.IOException: Stream Closed
            //fos.write("java".getBytes());
        }
    }
    /*
     * 字节输出流操作步骤:
     * A:创建字节输出流对象
     * B:调用write()方法
     * C:释放资源
     * 
     * public void write(int b):写一个字节
     * public void write(byte[] b):写一个字节数组
     * public void write(byte[] b,int off,int len):写一个字节数组的一部分
     */
    public class FileOutputStreamDemo2 {
        public static void main(String[] args) throws IOException {
            // 创建字节输出流对象
            // OutputStream os = new FileOutputStream("fos2.txt"); // 多态
            FileOutputStream fos = new FileOutputStream("fos2.txt");
    
            // 调用write()方法
            //fos.write(97); //97 -- 底层二进制数据    -- 通过记事本打开 -- 找97对应的字符值 -- a
            // fos.write(57);
            // fos.write(55);
            
            //public void write(byte[] b):写一个字节数组
            byte[] bys={97,98,99,100,101};
            fos.write(bys);
            
            //public void write(byte[] b,int off,int len):写一个字节数组的一部分
            fos.write(bys,1,3);
            
            //释放资源
            fos.close();
        }
    }
    /*
     * 如何实现数据的换行?
     *
     *         windows:
    
     *         linux:
    
     *         Mac:
     *         而一些常见的个高级记事本,是可以识别任意换行符号的。
     * 
     * 如何实现数据的追加写入?
     *         用构造方法带第二个参数是true的情况即可
     */
    public class FileOutputStreamDemo3 {
        public static void main(String[] args) throws IOException {
            // 创建字节输出流对象
            // FileOutputStream fos = new FileOutputStream("fos3.txt");
            // 创建一个向具有指定 name 的文件中写入数据的输出文件流。如果第二个参数为 true,则将字节写入文件末尾处,而不是写入文件开始处。
            FileOutputStream fos = new FileOutputStream("fos3.txt", true);
    
            // 写数据
            for (int x = 0; x < 10; x++) {
                fos.write(("hello" + x).getBytes());
                fos.write("
    ".getBytes());
            }
    
            // 释放资源
            fos.close();
        }
    }
    /*
     * 加入异常处理的字节输出流操作
     */
    public class FileOutputStreamDemo4 {
        public static void main(String[] args) {
            
            // 为了在finally里面能够看到该对象就必须定义到外面,为了访问不出问题,还必须给初始化值
            FileOutputStream fos = null;
            try {
                
                fos = new FileOutputStream("fos4.txt");
                fos.write("java".getBytes());
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                // 如果fos不是null,才需要close()
                if (fos != null) {
                    // 为了保证close()一定会执行,就放到这里了
                    try {
                        fos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    2、FileIntputStream:字节输入流,读数据

       字节输入流操作步骤:
        A:创建字节输入流对象
        B:调用read()方法读取数据,并把数据显示在控制台
        C:释放资源

      读取数据的方式:
        A:int read():一次读取一个字节,没有字节返回-1.
        B:int read(byte[] b):一次读取一个字节数组

    public class FileInputStreamDemo {
        public static void main(String[] args) throws IOException {
            File file = new File("tempfile\file.txt");
            //创建一个字节输入流对象,必须明确数据源,其实就是创建字节读取流和数据源相关联。
            FileInputStream fis = new FileInputStream(file);
            //读取数据。使用 read();一次读一个字节。
            int ch = 0;
            while((ch=fis.read())!=-1){
                System.out.println("ch="+(char)ch);
            }
            // 关闭资源。
            fis.close();
        }
    }
    public class FileInputStreamDemo2 {
        public static void main(String[] args) throws IOException {
            /*
             * 演示第二个读取方法, read(byte[]);
             */
            File file = new File("tempfile\file.txt");
            // 创建一个字节输入流对象,必须明确数据源,其实就是创建字节读取流和数据源相关联。
            FileInputStream fis = new FileInputStream(file);        
            //创建一个字节数组。
            byte[] buf = new byte[1024];//长度可以定义成1024的整数倍。        
            int len = 0;
            while((len=fis.read(buf))!=-1){
                System.out.println(new String(buf,0,len));
            }
            fis.close();
        }
    }

    3、文件的复制
        

          数据源:从哪里来
            a.txt -- 读取数据 -- FileInputStream 

          目的地:到哪里去
            b.txt -- 写数据  -- FileOutputStream

    1、通过字节流复制文件,速度慢

    public class CopyFileTest {
        public static void main(String[] args) throws IOException {
            //1,明确源和目的。
            File srcFile = new File("E:\1.mp3");
            File destFile = new File("E:\copy_2.mp3");
            
            //2,明确字节流 输入流和源相关联,输出流和目的关联。
            FileInputStream fis = new FileInputStream(srcFile);
            FileOutputStream fos = new FileOutputStream(destFile);
            
            //3,复制文件 使用输入流的读取方法读取字节,并将字节写入到目的中。
            int ch = 0;
            while((ch=fis.read())!=-1){
                fos.write(ch);
            }
            //4,关闭资源。
            fos.close();
            fis.close();
        }
    }

     2、通过自定义缓冲数组复制文件,速度快

    public class CopyFileByBufferTest {
        public static void main(String[] args) throws IOException {
            File srcFile = new File("E:\1.mp3");
            File destFile = new File("E:\copy_1.mp3");
            // 明确字节流 输入流和源相关联,输出流和目的关联。
            FileInputStream fis = new FileInputStream(srcFile);
            FileOutputStream fos = new FileOutputStream(destFile);
            //定义一个缓冲区。
            byte[] buf = new byte[1024];
            int len = 0;
            while ((len = fis.read(buf)) != -1) {
                fos.write(buf, 0, len);// 将数组中的指定长度的数据写入到输出流中。
            }
    
            // 4,关闭资源。
            fos.close();
            fis.close();
        }
    }

     4、缓冲区类(高效类)

    /*
     * 缓冲区类(高效类)
     * 写数据:BufferedOutputStream
     * 读数据:BufferedInputStream
     * 
     * 构造方法可以指定缓冲区的大小,但是我们一般用不上,因为默认缓冲区大小就足够了。
     * 
     * 为什么不传递一个具体的文件或者文件路径,而是传递一个OutputStream对象呢?
     * 原因很简单,字节缓冲区流仅仅提供缓冲区,为高效而设计的。但是呢,真正的读写操作还得靠基本的流对象实现。
     */
    public class BufferedOutputStreamDemo {
        public static void main(String[] args) throws IOException {
            // BufferedOutputStream(OutputStream out)
            // FileOutputStream fos = new FileOutputStream("bos.txt");
            // BufferedOutputStream bos = new BufferedOutputStream(fos);
            // 简单写法
            BufferedOutputStream bos = new BufferedOutputStream(
                    new FileOutputStream("bos.txt"));
    
            // 写数据
            bos.write("hello".getBytes());
    
            // 释放资源
            bos.close();
        }
    }
    /*
     * 注意:虽然我们有两种方式可以读取,但是,请注意,这两种方式针对同一个对象在一个代码中只能使用一个。
     */
    public class BufferedInputStreamDemo {
        public static void main(String[] args) throws IOException {
            // BufferedInputStream(InputStream in)
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
                    "bos.txt"));
    
            // 读取数据
            // int by = 0;
            // while ((by = bis.read()) != -1) {
            // System.out.print((char) by);
            // }
            // System.out.println("---------");
    
            byte[] bys = new byte[1024];
            int len = 0;
            while ((len = bis.read(bys)) != -1) {
                System.out.print(new String(bys, 0, len));
            }
    
            // 释放资源
            bis.close();
        }
    }

     5、4种读取方式的比较

    *
     * 需求:把e:\哥有老婆.mp4复制到当前项目目录下的copy.mp4中
     * 
     * 字节流四种方式复制文件:
     * 基本字节流一次读写一个字节:    共耗时:117235毫秒
     * 基本字节流一次读写一个字节数组: 共耗时:156毫秒
     * 高效字节流一次读写一个字节: 共耗时:1141毫秒
     * 高效字节流一次读写一个字节数组: 共耗时:47毫秒
     */
    public class CopyMp4Demo {
        public static void main(String[] args) throws IOException {
            long start = System.currentTimeMillis();
            // method1("e:\哥有老婆.mp4", "copy1.mp4");
            // method2("e:\哥有老婆.mp4", "copy2.mp4");
            // method3("e:\哥有老婆.mp4", "copy3.mp4");
            method4("e:\哥有老婆.mp4", "copy4.mp4");
            long end = System.currentTimeMillis();
            System.out.println("共耗时:" + (end - start) + "毫秒");
        }
    
        // 高效字节流一次读写一个字节数组:
        public static void method4(String srcString, String destString)
                throws IOException {
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
                    srcString));
            BufferedOutputStream bos = new BufferedOutputStream(
                    new FileOutputStream(destString));
    
            byte[] bys = new byte[1024];
            int len = 0;
            while ((len = bis.read(bys)) != -1) {
                bos.write(bys, 0, len);
            }
    
            bos.close();
            bis.close();
        }
    
        // 高效字节流一次读写一个字节:
        public static void method3(String srcString, String destString)
                throws IOException {
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
                    srcString));
            BufferedOutputStream bos = new BufferedOutputStream(
                    new FileOutputStream(destString));
    
            int by = 0;
            while ((by = bis.read()) != -1) {
                bos.write(by);
    
            }
    
            bos.close();
            bis.close();
        }
    
        // 基本字节流一次读写一个字节数组
        public static void method2(String srcString, String destString)
                throws IOException {
            FileInputStream fis = new FileInputStream(srcString);
            FileOutputStream fos = new FileOutputStream(destString);
    
            byte[] bys = new byte[1024];
            int len = 0;
            while ((len = fis.read(bys)) != -1) {
                fos.write(bys, 0, len);
            }
    
            fos.close();
            fis.close();
        }
    
        // 基本字节流一次读写一个字节
        public static void method1(String srcString, String destString)
                throws IOException {
            FileInputStream fis = new FileInputStream(srcString);
            FileOutputStream fos = new FileOutputStream(destString);
    
            int by = 0;
            while ((by = fis.read()) != -1) {
                fos.write(by);
            }
    
            fos.close();
            fis.close();
        }
    }
  • 相关阅读:
    床前思
    捍卫永恒的爱情,注定是一场梦境(转)
    耳朵生豆
    有志人士自行创业之十大策略
    思念熟睡的你
    如何用好云的弹性
    测试一年多,上线就崩溃!微服务到底应该怎么测试?
    解决Tengine健康检查引起的TIME_WAIT堆积问题
    解读容器的 2020:寻找云原生的下一站
    Java 过滤器的作用
  • 原文地址:https://www.cnblogs.com/flei/p/6617532.html
Copyright © 2020-2023  润新知