Java学习的第二十二天(JavaSE最终篇_IO流之字节流)

一、IO流知识体系总结

1.根据传输数据的方式不同分为:输入流(读数据)和输出流(写数据)
2.输入流和输出流 图解如下

内存------<-----硬盘  从硬盘中的数据读入内存称为读数据 输入
内存------>-----硬盘  从内存中的数据写入硬盘称为写数据 输出

3.硬盘和内存存储数据和读写速率的区别

硬盘:永久性的存储数据,读写速度慢
内存:临时性的存储数据,读写速度快

4.计算机原理知识分析

计算机存储数据的最小单元 (位)  1字节==8个位
字符如果想要存储 先要通过编码表转换成字节(二进制数)
中文字符--->字节(GBK(中文编码表)<--gb2312)
英文字符--->字节(ASCII(英文编码表))
不同的国家拥有不同的编码表  通用编码表:万国编码表---UTF-8(unicode编码表)

5.根据传输数据的类型不同分为:字节流和字符流(通过编码表转换成字节)

字符流用来操作文本文件  
字节流用来操作视频、图片、音频...
字符流能够做的事情字节流也是能做的

6.根据数据传输的类型分为下面四种类型

字节流: 
      1.字节输入流(读数据)  InputStream(抽象类) 需要使用子类FileInputStream
      2.字节输出流(写数据)  OutputStream(抽象类) 需要使用子类FileOutputStream
字符流: 
      1.字符输入流(读数据)  Reader(抽象类) 需要使用子类FilerReader
      2.字符输出流(写数据)  Writer(抽象类) 需要使用子类FileWriter*/

二、如何使用IO流对文本文件进行读操作

1.通过使用read()对文本中的“hello world”进行一个一个字节的读

package com.bianyiit.cast;

import java.io.*;

public class IODemo2 {
    public static void main(String[] args) throws IOException {
        //创建一个文件对象
        File file = new File("D:\\重要代码Demo\\文件IO对象\\FileDemo1\\file01.txt");
        //创建一个指向具体的文件对象的字节输入流对象
        InputStream s=new FileInputStream(file);  //传入的参数是一个文件对象
        //通过一个字节一个字节的读数据
        byte onebyte = (byte) s.read();
        System.out.println("h的ASCII:"+onebyte);   //ASCII码值
        System.out.println("104对应的英文单词:"+(char)onebyte);
        //继续读取下一个字节
        System.out.println("继续读取下一个字节"+(char)s.read());
        System.out.println("继续读取下一个字节"+(char)s.read());
        System.out.println("继续读取下一个字节"+(char)s.read());
        System.out.println("继续读取下一个字节"+(char)s.read());
    }
}
//输出结果:
	h的ASCII:104
	104对应的英文单词:h
	继续读取下一个字节e
	继续读取下一个字节l
	继续读取下一个字节l
	继续读取下一个字节o	

2.使用循环代替一个一个字节的读数据的方式

package com.bianyiit.cast;

import java.io.*;

public class IODemo3 {
    public static void main(String[] args) throws IOException {
        //创建一个文件对象
        File file = new File("D:\\重要代码Demo\\文件IO对象\\FileDemo1\\file01.txt");
        //创建一个指向具体的文件对象的字节输入流对象
        InputStream s=new FileInputStream(file);
        //使用循环去读取字节第一种方式
        //调用read()读数据的时候,当返回值不等于-1时代表还有数据可以读取
        //s.read()代表读到了一个字节,然后抽取出来
        int read;
        while((read=s.read())!=-1){
            System.out.print((char)read);
        }
        //使用循环去读取字节第二种方式(读一个字节就放到字节数组里面)
        //定义一个字节数据
        /*byte[] arr=new byte[1024];
        //读一个放一个
        byte b1 = (byte)s.read();
        arr[0]=b1;
        byte b2 = (byte)s.read();
        arr[1]=b2;
        //将字节数组转换成字符串
        String s1 = new String(arr, 0, 2);
        System.out.println(s1);*/
    }
}

注意:

//正确示例代码:
File file = new File("D:\\重要代码Demo\\文件IO对象\\FileDemo1\\file01.txt");
InputStream s=new FileInputStream(file);
int read;
while((read=s.read())!=-1){
   System.out.print((char)read);
}
//输出结果:
	hello world
//错误示例代码
File file = new File("D:\\重要代码Demo\\文件IO对象\\FileDemo1\\file01.txt");
InputStream s=new FileInputStream(file);
while(s.read()!=-1){
   System.out.print((char)s.read());
}
//输出结果:
	e
	l
	 
	o
	l
	￿
//为什么会出现上述的情况呢??我们通过观察后发现,输出打印的是hello world的2、4、6、8、10、12的位置的内容,这是因为我们使用了read()之后指针就会指向下一个字符,如果不输出这个字符,在括号里面再次使用read()之后,上面的h由于没有保存就不会输出打印,然后继续判断,因此hello world while中的read()指向的是hlowrd 而括号中的read()指向的就是el olX

3.上述两种循环读取字节的方法合二为一后优化如下

package com.bianyiit.cast;

import java.io.*;

public class IODemo3 {
    public static void main(String[] args) throws IOException {
        //创建一个文件对象
        File file = new File("D:\\重要代码Demo\\文件IO对象\\FileDemo1\\file01.txt");
        //创建一个指向具体的文件对象的字节输入流对象
        InputStream s=new FileInputStream(file);
        //调用read()读数据的时候,当返回值不等于-1时代表还有数据可以读取
        //定义一个字节数组
       /* byte[] arr=new byte[1024];
        int read;
        int i=0;  //定义数组真正读到字节的个数
        while ((read=s.read())!=-1){
            arr[i]=(byte)read;
            i++;
        }
        //将字节数组转换成字符串
        String s2 = new String(arr, 0, i);
        System.out.println(s2);

4.由于一个一个字节的读还是太慢了,所以下面我们采用1024个字节为一组,循环读入数据进内存

package com.bianyiit.cast;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class IODemo4 {
    public static void main(String[] args) throws IOException {
        //使用字节输入流一次读取一个字节数组
        //如果输入了错误的文件,会输出系统找不到指定的文件
        FileInputStream is = new FileInputStream(new File("D:\\重要代码Demo\\文件IO对象\\FileDemo1\\file01.txt"));
        byte[] arr = new byte[1024];
        //byte[] arr = new byte[1024*2];
        /*//一次读一个字节数组(一次读1024个字节)
        int length = is.read(arr);
        String s = new String(arr, 0, length);
        System.out.println(s);*/
        //如何把文件里面的数据全部读完
        int read;
        while((read=is.read(arr))!=-1){
            String s1 = new String(arr, 0, read);
            System.out.println(s1);
        }
    }
}

三、如何使用IO流对文本文件进行写操作

package com.bianyiit.cast;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class OutputDemo1 {
    public static void main(String[] args) throws IOException {
        //使用字节输出流写数据
        FileOutputStream os = new FileOutputStream(new File("D:\\重要代码Demo\\文件IO对象\\FileDemo1\\file02.txt"),true);
        //使用os字节输出流对象往file02.txt中写数据
        String s="I am sunshine boy";
        //将字符串转换成字节数组
        byte[] bytes = s.getBytes();
        //将一个字节数组写入文件中
        os.write(bytes);
        System.out.println("写入成功!!");
        //重复写入数据会覆盖,如果想往文件中追加数据,需要在fileoutputstream中的括号中添加一个参数:true (默认是false)
    }
}

提示:重复写入数据会覆盖,如果想往文件中追加数据,需要在fileoutputstream中的括号中添加一个参数:true (默认是false)

四、如何使用IO流进行文本文件的复制

package com.bianyiit.cast;

import java.io.*;

public class InputStreamAndOutputStream {
    public static void main(String[] args) throws IOException {
        //文件的复制
        /*分析:将file01.txt中的内容复制一份到file03.txt中
        * 准备输入输出流对象
        * 对于file02.txt是读,对于file03.txt是写*/
        //读出file02.txt中的文件
        FileInputStream is = new FileInputStream(new File("D:\\重要代码Demo\\文件IO对象\\FileDemo1\\file02.txt"));
        FileOutputStream os = new FileOutputStream(new File("D:\\重要代码Demo\\文件IO对象\\FileDemo1\\file03.txt"));
        byte[] bytes = new byte[1024];
        int length;
        while((length=is.read(bytes))!=-1){  //一定要注意is.read(),括号里需要传入字节数组对象
            os.write(bytes,0,length);
        }
    }
}

注意:is.read(),括号里需要传入字节数组对象 while((length=is.read(bytes))!=-1){}

五、如何使用IO流进行图片的复制

package com.bianyiit.cast;

import java.io.*;

public class CopyTuPian {
    public static void main(String[] args) throws IOException {
        //申请了两个资源空间
        //创建输出流对象
        FileInputStream is = new FileInputStream(new File("D:\\重要代码Demo\\文件IO对象\\FileDemo1\\preview.jpg"));
        FileOutputStream os = new FileOutputStream(new File("D:\\重要代码Demo\\文件IO对象\\girl.jpg"));
        //读取图片的内容
        //一次读一个字节数组
        byte[] arr=new byte[1024];
        int length;
        while((length=is.read(arr))!=-1){
            os.write(arr,0,length);
        }
        //释放资源空间  close()
        is.close();
        is.close();
    }
}

六、IO流的标准写法,使用try{}catch(){}finally{}

package com.bianyiit.anli;

import java.io.*;

public class Demo1 {
    public static void main(String[] args) throws IOException {
        //输入输出流的标准代码规范
        //申请了两个资源空间
        //创建输出流对象
        FileInputStream is = null;
        FileOutputStream os = null;
        try {
            is = new FileInputStream(new File("D:\\重要代码Demo\\文件IO对象\\FileDemo1\\preview.jpg"));
            os = new FileOutputStream(new File("D:\\重要代码Demo\\文件IO对象\\girl.jpg"));
            //读取图片的内容
            //一次读一个字节数组
            byte[] arr=new byte[1024];
            int length;
            while((length=is.read(arr))!=-1){
                os.write(arr,0,length);
            }
        } catch (IOException e) {
            //e.printStackTrace();
        } finally {
            //释放资源空间  close()
            //假如流对象没有创建成功的情况下就不需要关闭流空间
            if(is!=null){
                is.close();
            }
            if(os!=null){
                os.close();
            }
        }
    }
}

七、IO流释放资源的三种方式

第一种方式:使用 finally{释放资源}

package com.bianyiit.anli;

import java.io.*;

public class Demo1 {
    public static void main(String[] args) throws IOException {
        //输入输出流的标准代码规范
        //申请了两个资源空间
        //创建输出流对象
        FileInputStream is = null;
        FileOutputStream os = null;
        try {
            is = new FileInputStream(new File("D:\\重要代码Demo\\文件IO对象\\FileDemo1\\preview.jpg"));
            os = new FileOutputStream(new File("D:\\重要代码Demo\\文件IO对象\\girl.jpg"));
            //读取图片的内容
            //一次读一个字节数组
            byte[] arr=new byte[1024];
            int length;
            while((length=is.read(arr))!=-1){
                os.write(arr,0,length);
            }
        } catch (IOException e) {
            //e.printStackTrace();
        } finally {
            //关流的第一种方式:释放资源空间  close()
            //假如流对象没有创建成功的情况下就不需要关闭流空间
            if(is!=null){
                is.close();
            }
            if(os!=null){
                os.close();
            }
        }
    }
}

第二种方式:自定义一个关闭IO流的工具类IOTools

package com.bianyiit.anli;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class IOTools {
    public static void close(InputStream is, OutputStream os) throws IOException {
        //释放资源空间  close()
        //假如流对象没有创建成功的情况下就不需要关闭流空间
        if(is!=null){
            is.close();
        }
        if(os!=null){
            os.close();
        }
    }
}
package com.bianyiit.anli;

import java.io.*;

public class Demo1 {
    public static void main(String[] args) throws IOException {
        //输入输出流的标准代码规范
        //申请了两个资源空间
        //创建输出流对象
        FileInputStream is = null;
        FileOutputStream os = null;
        try {
            is = new FileInputStream(new File("D:\\重要代码Demo\\文件IO对象\\FileDemo1\\preview.jpg"));
            os = new FileOutputStream(new File("D:\\重要代码Demo\\文件IO对象\\girl.jpg"));
            //读取图片的内容
            //一次读一个字节数组
            byte[] arr=new byte[1024];
            int length;
            while((length=is.read(arr))!=-1){
                os.write(arr,0,length);
            }
        } catch (IOException e) {
            //e.printStackTrace();
        } finally {
            //关流的第二种方式:使用自定义的关流工具类
            IOTools.close(is,os);
        }
    }
}

第三种方式:JDK7版本提供的一种新特性,用来关流

package com.bianyiit.anli;

import java.io.*;

public class GuanLiuDemo3 {
    public static void main(String[] args) throws IOException {
        //JDK7版本提供的一种新特性,用来关流
        //try(流对象){操作的代码}  不需要使用了close()
        try(
                //将流对象放在小括号里面,就可以实现自己自动去关流
                FileInputStream is = new FileInputStream(new File("D:\\重要代码Demo\\文件IO对象\\FileDemo1\\preview.jpg"));
                FileOutputStream  os = new FileOutputStream(new File("D:\\重要代码Demo\\文件IO对象\\girl.jpg"));
           ){
				//这里写你想要对文件进行读写的操作
			}
    }
}
发布了73 篇原创文章 · 获赞 11 · 访问量 2472

猜你喜欢

转载自blog.csdn.net/weixin_43908333/article/details/103168620