IO流相关知识点(字节流)

IO流有分类方式 1.按的方向分为:输入流和输出流; 2.按的数据单位不同分为字节流和字符流; 3.按的功能不同分为:节点流和处理流。

下面我们谈一谈流相关知识点:

  • 输入流 :把数据从其他设备上读取到内存中的流。
  • 输出流 :把数据从内存 中写出到其他设备上的流。
    根据数据的类型分为:字节流字符流
  • 字节流 :以字节为单位,读写数据的流。
  • 字符流 :以字符为单位,读写数据。

***看到这里你可能会想什么是流呢?什么时候该用具体的什么流呢?***

 1.    流具有方向性,至于是输入流还是输出流则是一个相对的概念,一般以程序为参考,如果数据的  流向是程序至设备,我们成为输出流,反之我们称为输入流。

可以将流想象成一个“水流管道”,管道中的水自然就是传送的数据了,自然就出现了方向的概念。

当程序需要从某个数据源读入数据的时候,就会开启一个输入流,数据源可以是文件、内存或网络等等。相反地,需要写出数据到某个数据源目的地的时候,也会开启一个输出流,这个数据源目的地也可以是文件、内存或网络等等。

  2.   那什么时候用什么流呢,如果你需要传送的文件你打开之后,你可以看明白它的内容,你就用字符流,你看不明白你就用字节流,要是你根据以上方法你还不明白用什么流,你就用字节流,因为字节流是万能流。

我们谈一谈字节流

  字节流又分为字节输入流,字节输出流 ,字节缓冲输入流和字节缓冲输出流

(注意:字节缓冲流传输的效率是普通输入流的200多倍(为什么呢,后文有解答),所以我们优先选择缓冲流)

 字节输出流FileOutputStream;向指定路径写入数据(数据从硬盘输出到内存)

 字节输入流FileInputStream;  把指定路径中的数据读取出来(数据从内存输入硬盘)

记忆小技巧:Out对应write()方法,In对应read()方法,真好相反。

如下图(加深记忆):

 字节流代码实现:

public class IoDemo {
    public static void main(String[] args) throws IOException {
        //字节输出流
        FileOutputStream fos = new FileOutputStream("D:\\mycode\\word.txt");
        //上面这串代码相当于 FileOutputStream fos=new FileOutputStream(new File("D:\\mycode\\word.txt"));
        /*
            做了三件事:
                A.调用了系统的功能创建了文件
                B.创建了字节输出流对象
                C.让字节输出流对象指向创建好的文件
         */
        //一次写一个字节
        fos.write(97);//文件中显示 “a”;

        //一次写一个字节数组
        //byte[] bys={97,98,99,100,101};
        //byte[].getBytes():返回字符串对应的字节数组
        byte[] bys = "abcde".getBytes();
        fos.write(bys);

        //写入数据是我们如何实现换行呢?//  \r\t是换行符
        fos.write("\r\n".getBytes());

        //写数据时我们如何追加写入数据呢?
        //在创建对象时给两个参数,第一个是FIle对象,第二个给true
        //FileOutputStream out=new FileOutputStream(new File(" "),true);

        fos.close();//在IO流中这一步操作是必须进行的,释放资源和与此流相关的系统资源。
        //,而为了保证这一操作绝对执行,java提供了finally语句块 ,具体执行操作如下:

        FileOutputStream out = null;
        try {
            out = new FileOutputStream(new File("D:\\mycode\\word1.txt "), true);

            out.write("javase".getBytes());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            out.close();
        }
        //字节输入流
//        FileInputStream fis = new FileInputStream("D:\\mycode\\word.txt");
          BufferedInputStream fis = new BufferedInputStream(new FileInputStream("D:\\mycode\\word.txt"));


        //用一次读一个字节的方法读完Word.txt文件
//        int by;
//        while ((by = fis.read()) != -1) {
//        /*
//          fis.read ();读数据
//          by=fis.read();把读取到的数据赋值给by
//          by!=-1;判断读取到的数据是否为-1
//         */
//            System.out.println((char) by);
//        }
        try {
            //用一次读一个字节数组的方法读完Word.txt文件
            byte[] bys1 = new byte[1024];//[]中可以是1024及1024的整倍数
            int len;
            while ((len = fis.read(bys1)) != -1) {

                System.out.println(new String(bys1, 0, len));//aabcde
                System.out.println(bys1);//[B@1b6d3586
                //String (byte[] bys)将bys字节数组toString
                //String (byte[] bys,int offset,int len)将bys字节数组从offset索引开始向后len长度的元素toString
            }
        } finally {
            fis.close();
        }

    }

}

 字节流写数据与读数据的具体方法:

字节流写数据的三个方法:
                void write(int b):将指定字节写入此文件输出流、一次写一个字节
                void write(byte[] b):将b.length字节的字节数组写入输出流、一次写一个字节数组
                  byte[].getBytes():根据一个字符串返回对应的字节数组  例如“abcde”.getBytes;
                void write(byte[] b,int off,int len):一次写一个字节数组的一部分
             字节流读数据的三个方法:
                int read();从该输入流中读取数据一次读一个字节
                int read(byte[] b);从该输入流中读取数据一次读一个字节数组

字节缓冲输出流:BufferedOutputStream

字节缓冲输入流:BufferedInputStream

 构造方法:

     BufferedOutputStream(new FileOutputStream)

     BufferedInputStream(new FileInputStream)

你可能会想为什么构造方法的参数不是一个路径呢? 

原因:字节缓冲流,它提供的仅仅是一个缓冲区,真正读写数据还是得靠字节流对象

为什么缓冲流的效率是普通流的200多倍呢? 

缓冲流和普通流 就好比是两辆火车,以固定速度拉同数量的乘客到某地,一次拉1个和一次拉100个,当然是后者的效率更快了,   下面我们用代码来比较:

代码实现如下:

public class MyTest {
	public static void main(String[] args) throws IOException {
		File data = new File("C:/Mu/data.zip");
		File a = new File("C:/Mu/a.zip");
		File b = new File("C:/Mu/b.zip");

		StringBuilder sb = new StringBuilder();

		long start = System.currentTimeMillis();
		copy(data, a);
		long end = System.currentTimeMillis();

		long start2 = System.currentTimeMillis();
		bufferedCopy(data, b);
		long end2 = System.currentTimeMillis();

		System.out.println("普通字节流耗时:" + (end - start) + " ms");
		System.out.println("缓冲字节流耗时:" + (end2 - start2) + " ms");
	}

	// 普通字节流
	public static void copy(File in, File out) throws IOException {
		// 封装数据源
		InputStream is = new FileInputStream(in);
		// 封装目的地
		OutputStream os = new FileOutputStream(out);
		
		int by = 0;
		while ((by = is.read()) != -1) {
			os.write(by);
		}
		is.close();
		os.close();
	}

	// 缓冲字节流
	public static void bufferedCopy(File in, File out) throws IOException {
		// 封装数据源
		BufferedInputStream bi = new BufferedInputStream(new FileInputStream(in));
		// 封装目的地
		BufferedOutputStream bo = new BufferedOutputStream(new FileOutputStream(out));
		
		int by = 0;
		while ((by = bi.read()) != -1) {
			bo.write(by);
		}
		bo.close();
		bi.close();
	}
}

 运行结果:

普通字节流耗时:184867 ms
缓冲字节流耗时:752 ms

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值