JavaIO-字节流(InputStream输入流、OutputStream输出流)

一)JavaIO流

概述:IO流用来处理设备之间的数据传输,Java操作是通过流的方式实现,工具类都在jdk中的java.io.*包和java.nio.*包下。

流向:InputStream读取数据、OutputStream写数据。

类型:字节流,可以操作任何类型的数据,在计算机中任何数据都是以字节存储的。

           字符流,适用于操作纯字符的数据。

 

二)InputStream&FileInputStream输入流

初始化构造方法:

1)FileInputStream(String name) 

     通过打开与实际文件的连接来创建一个FileInputStream,该文件由文件系统中的路径名name命名。

2)FileInputStream(File file) 

     通过打开与实际文件的连接创建一个FileInputStream,该文件由文件系统中的File对象file命名。 

 

读取数据方法:

1)read() ,从输入流中读取一个字节的数据。

2)read(byte[] b) ,从输入流读取最多b.length个字节的数据,返回一个字节数组。

3)read(byte[] b, int off, int len) ,从输入流读取最多len字节的数据,返回一个字节数组。

 

代码实现:

方式一:一次读取一个字节数据,该方式不建议使用,因为如果文件比较大,执行的时间太长。

/**
 * 字节输入流
 * 方式一: 一次读取一个字节数据,该方式不建议使用,因为如果文件比较大,执行的时间太长。
 * 1、read方法每次读文件1个字节(byte), 把byte转成int返回
 * 2、当读到后的时候, 返回-1, -1表示读取文件结束
 * @throws IOException
 */
public static void inputRead() {
    long start = System.currentTimeMillis();
		
    InputStream input = null;
    try {
        // 第一种传值方式
        //input = new FileInputStream("D:\\io\\1MB.rar");
			
        // 第二种传值方式
        input = new FileInputStream(new File("D:\\io\\1MB.rar")); // 读取1MB文件,大概需要3.6秒
			
        // 一次读取一个字节
        int len = 0;
        while ((len = input.read()) != -1) {
            // 打印,如此处增加一些其它操作,耗时会多一点
				
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (input != null) {
                input.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    long end = System.currentTimeMillis();
    System.out.println("一次读取一个字节的方式,总共耗时" + (end-start) + "ms");
}

 

方式二:一次读取byte个字节数据,当读到最后的时候,会返回-1,-1表示文件读取结束。

/**
 * 字节输入流
 * 方式二:一次读取byte个字节数据,当读到最后的时候,会返回-1,-1表示文件读取结束。
 * @throws IOException
 */
public static void inputReadBytes() {
    long start = System.currentTimeMillis();
		
    InputStream input = null;
    try {
        input = new FileInputStream(new File("D:\\io\\446MB.rar")); // 读取446MB文件,大概需要0.3秒
			
        // 一次读取byte[1024]个字节
        // 一次读取byte[1024*8]个字节
        byte[] bytes = new byte[1024*8];
			
        int len = 0;
        while ((len = input.read(bytes)) != -1) {
            // 打印,如此处增加一些其它操作,耗时会多一点
				
            // 处理txt中的中文乱码情况
            //String s = new String(bytes, 0, len, "GBK");
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (input != null) {
                input.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
		
    long end = System.currentTimeMillis();
    System.out.println("一次读取byte个字节的方式,总共耗时" + (end-start) + "ms");
}

 

三)OutputStream&FileOutputStream输出流

初始化构造方法:

1)FileOutputStream(String name) 

2)FileOutputStream(File file) 

     说明:创建一个新文件,添加输入内容。

 

3)FileOutputStream(String name, boolean append) 

4)FileOutputStream(File file, boolean append) 

     说明:如文件不存在,先创建文件,然后在现有的文件末尾追加输入的内容。

 

读取数据方法:

1)write(int b) ,从输出流写入一个字节的数据。

2)write(byte[] b) ,从输出流写入最多b.length个字节的数据。

3)write(byte[] b, int off, int len) ,从输出流写入最多len字节的数据。

 

代码实现:

方式一:一次输出一个字节数据,该方式不建议使用,执行效率太低。

/**
 * 字节输出流
 * 方式一:一次输出一个字节数据,该方式不建议使用,执行效率太低。
 * @throws IOException
 */
public static void outputWrite() {
    long start = System.currentTimeMillis();
		
    OutputStream output = null;
    try {
        // 第一种传值方式
        //output = new FileOutputStream("D:\\io\\output.txt"); // 创建一个新文件,添加输入内容
			
        // 第二种传值方式
        //output = new FileOutputStream("D:\\io\\output.txt", true); // 如文件不存在,先创建文件, 然后在现有的文件末尾追加输入的内容
			
        // 第三种传值方式
        output = new FileOutputStream(new File("D:\\io\\output.txt")); // 创建一个新文件,添加输入内容
			
        // 第四种传值方式
        //output = new FileOutputStream(new File("D:\\io\\output.txt"), true); // 如文件不存在,先创建文件, 然后在现有的文件末尾追加输入的内容
			
        //  一次输出一个字节
        output.write(97); // a
        output.write(98); // b
        output.write(99); // c
        output.write(100); // d
        output.write("偶是输出流".getBytes()); // 中文
        output.write("中文格式字符串".getBytes("UTF-8")); // 中文
			
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (output != null) {
                output.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
	
    long end = System.currentTimeMillis();
    System.out.println("一次输出一个字节,总共耗时" + (end-start) + "ms");
}

 

方式二:一次输出byte个字节数据。

/**
 * 字节输出流
 * 方式二:一次输出byte个字节数据。
 * @throws IOException 
 */
public static void outputWriteBytes() {
    long start = System.currentTimeMillis();
		
    OutputStream output = null;
    try {
        output = new FileOutputStream(new File("D:\\io\\output.txt")); // 创建一个新文件,添加输入内容
			
        //  一次输出byte个字节
        byte[] bytes = {97, 98, 99, 100};
        output.write(bytes);
			
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (output != null) {
                output.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
		
    long end = System.currentTimeMillis();
    System.out.println("一次输出byte个字节,总共耗时" + (end-start) + "ms");
}

 

四)InputStream输入流、OutputStream输出流

方式一:字节输入流和字节输出流实现文件拷贝,一次读取一个字节数据,不建议使用。

/**
 * 方式一:字节输入流和字节输出流实现文件拷贝,一次读取一个字节数据,不建议使用。
 * @throws IOException 
 */
public static void inputAndOutput() {
    long start = System.currentTimeMillis();
		
    InputStream input = null;
    OutputStream output = null;
    try {
        input = new FileInputStream(new File("D:\\io\\1MB.rar")); // 读取1MB文件,大概需要3.6秒
			
        output = new FileOutputStream(new File("D:\\io\\output_1MB.rar"));
			
        // 一次读取一个字节
        int len = 0;
        while ((len = input.read()) != -1) {
            output.write(len);
        }
			
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (input != null) {
                input.close();
            }
            if (output != null) {
                output.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
		
    long end = System.currentTimeMillis();
    System.out.println("字节输入流和输出流实现文件拷贝,总共耗时" + (end-start) + "ms"); // 1MB文件, 总共耗时大概9秒
}

 

方式二:字节输入流和字节输出流实现文件拷贝,一次读取1024*8个字节数据。

每次只读一个字节数据,会耗时太慢。一次性读一个文件的所有数据,内存可能装不下。分批读写。

/**
 * 方式二:字节输入流和输出流实现文件拷贝,一次读取1024*8个字节数据。
 * @throws IOException 
 */
public static void inputAndOutputBytes() {
    long start = System.currentTimeMillis();
		
    InputStream input = null;
    OutputStream output = null;
    try {
        input = new FileInputStream(new File("D:\\io\\446MB.rar")); // 读取446MB文件,大概需要0.3秒
			
        output = new FileOutputStream(new File("D:\\io\\output_446MB.rar")); // 创建一个新文件,添加输入内容
			
        /*
         * 每次只读一个字节数据,会耗时太慢。一次性读一个文件的所有数据,内存可能装不下。分批读写。
         * 解决方法: 分批读写,定义每次读8KB
         */
        // 定义个8kb字节数组,作为缓冲区流
        byte[] bytes = new byte[1024*8];
			
        int len = 0;
        while ((len = input.read(bytes)) != -1) {
            //output.write(len); // 这种直接读取的方式,可能会损坏文件,导致用不了
				
            output.write(bytes, 0, len);
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (input != null) {
                input.close();
            }
            if (output != null) {
                output.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
		
    long end = System.currentTimeMillis();
    System.out.println("字节输入流和输出流实现文件拷贝,总共耗时" + (end-start) + "ms"); // 446MB文件, 总共耗时大概2.6秒
}

 

方式三:字节输入流和字节输出流实现文件拷贝,用http的方式读取远程文件,需借助一个工具类。

/**
 * 方式三:字节输入流和字节输出流实现文件拷贝,用http的方式读取远程文件,需借助一个工具类。
 * @throws IOException 
 */
public static void inputAndOutputHttp() {
    long start = System.currentTimeMillis();
		
    // 远程文件地址
    String requestUrl = "https://localhost:8080/oysept/测试1.rar";
		
    InputStream input = null;
    OutputStream output = null;
    try {
        // 获取远程文件InputStream,跟网速有很大的关系,网速快,读取就快,网速慢,读取就慢
        input = getHttpInputStream(requestUrl, "GET");
			
        output = new FileOutputStream(new File("D:\\io\\output_file_test.rar"));
			
        /*
         * 每次只读一个字节数据,会耗时太慢。一次性读一个文件的所有数据,内存可能装不下。分批读写。
         * 解决方法: 分批读写,定义每次读8KB
         */
        // 定义个8kb字节数组,作为缓冲区流
        byte[] bytes = new byte[1024*8];
			
        int len = 0;
        while ((len = input.read(bytes)) != -1) {
            //output.write(len); // 这种直接读取的方式,可能会损坏文件,导致用不了
				
            output.write(bytes, 0, len);
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (input != null) {
                input.close();
            }
            if (output != null) {
                output.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
		
    long end = System.currentTimeMillis();
    System.out.println("http方式,字节输入流和输出流实现拷贝文件,总共耗时" + (end-start) + "ms"); // 46.8MB的文件,一般网速,总共耗时大概29秒
}

http工具类:

/**
 * http获取远程文件的InputStream
 * @param requestUrl: 请求路径
 * @param requestMethod: 请求方式(GET、POST)
 * @return
 */
public static InputStream getHttpInputStream(String requestUrl, String requestMethod) {
    HttpURLConnection con = null;
    InputStream is = null;
    try {
        URL url = new URL(requestUrl);
			
        // 原生访问http请求,未代理请求
        con = (HttpURLConnection) url.openConnection();
        con.setDoOutput(true);
        con.setDoInput(true);
        con.setUseCaches(false);
        con.setRequestMethod(requestMethod);
        con.setReadTimeout(60000);
        con.setConnectTimeout(60000);
        con.connect();
			
        // 获取InputStream
        is = con.getInputStream();
        return is;
    } catch (IOException e) {
        System.out.println("getHttpInputStream error!" + e);
    }
    return null;
}

 

识别二维码关注个人微信公众号

本章完结,待续,欢迎转载!
 
本文说明:该文章属于原创,如需转载,请标明文章转载来源!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值