首页 > 代码库 > java学习笔记 --- IO(2)

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:\r\n
 *         linux:\n
 *         Mac:\r
 *         而一些常见的个高级记事本,是可以识别任意换行符号的。
 * 
 * 如何实现数据的追加写入?
 *         用构造方法带第二个参数是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("\r\n".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();
    }
}

 

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