IO流的字节流和字符流相关内容

声明

 首先在学习io流的时候一定要看明白字节流和字符流的的父类。关系如下 :

一,字节流 

注意事项,

1,用完流一定要手动关闭,

2,用到read读取方法的时候,是按照一个字节一个字节来读取。

3,如果按照常规的read方法读取的结果如果存在汉字,会出现乱码

4,流的读取是依次向下的,如果你已经读取一个流的部分内容,但是未读取完毕,那么接下来的再次出现读取该流的内容的时候,会接着往下面继续读,无法返回已经读取过的位置

5,在使用书写的时候,要注意字节流书写的参数是int类型,如果范围在-128---127内,会出现正常的值(可能是字母,数字,符号),如果超出这个范围。就会乱码 

6,在没有设置文件流是添加的情况下,书写会覆盖掉原本的值

文档准备:注意每个文档的内容和名称

代码演示如下:

字节输入流

//    IO流文件的读取
    public static void main(String[] args) throws Exception {
//        首先创建一个文件流对象,获取到到文件  路径可以用相对路径也可以用绝对路径
//          todo 绝对路径
//        InputStream is=new FileInputStream("D:\\Cllection\\day17\\src\\com\\haogu\\write.txt");
//          todo 相对路径
        InputStream is=new FileInputStream("src/com/haogu/write.txt");
        InputStream is2=new FileInputStream("src/com/haogu/write2.txt");
        InputStream is3=new FileInputStream("src/com/haogu/write3.txt");
//   读取文件的内容
        System.out.println("注意输出三次会发现他是依次向下输入内容,而不是重复输出第一个内容");
//        io是一个流的形式 读取是向下流动读取
        System.out.println(is2.read());
        System.out.println(is2.read());
        // TODO:内容读取完毕之后继续读取会输出-1
        //  并且发现他们读取出来的数据是unicode编码值想要文件的具体内容需要格式转化
//          在接下来的循环里面展示
        System.out.println(is2.read());


        int num;
        System.out.println("如果有文字的情况下会出现乱码:因为常用文字在utf-8占三个字符,不常用文字占4个字符");
        System.out.println("字符流输出只能一个一个字节去输出");
        while((num=is.read())!=-1){

            System.out.print((char)num);
        }



//        为了避免乱码调整的策略
//        处理乱码方式
//先定义一个字节数组(晚点用来保存读出来数据),数组的长度就是你这个数组能存放的最大的字节数
        System.out.println();
        System.out.println("=============解决乱码方案======================");
        byte[] bytes=new byte[20];
//      todo 难点!!!
//        在下方循环中,需要着重理解read(bytes)  本来我们read()是一个字节一个字节读取
//        在这里我传入数组,意味着不是一个一个读取,已经是一次性读取1024个字节而不是一次,一次的读取
//        而这里的num则是你每次读取的内容,
//        注意我这里没有用write.txt而是用他的副本write3.txt的原因是,
//        上方展示乱码的时候,write的流已经读取完了,再读直接就是读到-1,和我最初演示的io是一个流的形式同理
        while((num=is3.read(bytes))!=-1){
            System.out.println(num);
            System.out.println(Arrays.toString(bytes));
            System.out.println(new String(bytes,0,num));

        }
//        第三种读取方式根据文件的自己大小来读取,好处不会创建过大的数租节省空间,缺点,long转int会造成精度丢失
        InputStream is4=new FileInputStream("src/com/haogu/write4.txt");
        File file=new File("src/com/haogu/write4.txt");

//        转换会造成精度的丢失
        byte[] bytes2=new byte[(int) file.length()];
        while((num=is4.read(bytes2))!=-1){
//            可以看到数组的内部没有多余的0
            System.out.println(Arrays.toString(bytes2));
        }
//





//        最后关闭流
        is.close();
        is2.close();
        is3.close();
    }

        

字节输出流

注意文档被覆盖的情况我不在演示自己操作。

 public static void main(String[] args) throws Exception {
        OutputStream os=new FileOutputStream("src/com/haogu/Java02/write2.txt");
//        在文件中书写操作,这里用的文件和读取文件用的文件一样
//        注意 字节的范围是-128--127 所以传入的范围在这个范围内,大于这个返回会乱码
//        todo 发现覆盖了原本的文档内容此时  同时字节流输入的参数要求是int 字符流是str

//            如果想要不覆盖可以再创建文件流对象的时候在后面的参数书写为true
        OutputStream os2=new FileOutputStream("src/com/haogu/Java02/write2.txt",true);
        os.write(123);
        os2.write(64);
        os2.write(62);
        os2.write(63);
        os2.write(127);
        os2.write(128);
        os2.write(-128);
        os2.write(-129);
//     发现{os(输入就会覆盖原本文档的对象流)输入的{没有被覆盖,
//     而os2(不会覆盖原本文档的对象流)输入的内容内有覆盖原本的文档
//超过范围的部分乱码了
//        如果想要传入中文汉字,那么需要获取到汉字的字节格式例子如下
        String str="测试传入中文汉字";
      byte[] bytes=  str.getBytes();
      os2.write(bytes);

    }

 

字符流 

注意事项

1,在字符流读取的时候,他是按照字符来读取,即使你的文件里面有字节内容,依旧是可以读取的,会默认进行隐形转换,把字节转化为字符。

2,字符流使用read()读出来的编码依旧是unicode编码。(在我的案例里面,存放如char数组的过程中 会把unicode编码转化为字符,然后存入到你的字符数组内)

3,流的读取是依次向下的,如果你已经读取一个流的部分内容,但是未读取完毕,那么接下来的再次出现读取该流的内容的时候,会接着往下面继续读,无法返回已经读取过的位置
4,在没有设置文件流是添加的情况下,书写会覆盖掉原本的值

5,他的wirte()方法传入的是字符串,并且他写入的结果不是直接写入,而是先存入到磁盘缓冲区,在你关闭流之后,他才会存入到文件里面

代码如下

字符输入流 

文档准备:

代码如下

//    说完了字节接下来来说字符 他们的区别在于 字节的父类是 Output和Input而   字符是Read 和Write
public static void main(String[] args) throws IOException {
    Reader re=new FileReader("src/com/haogu/Java03/wirte1.txt");
    Reader re2=new FileReader("src/com/haogu/Java03/wirte2.txt");
    
//    普通读取
//可以看到读出来的依旧是unicode编码
    System.out.println(  re.read());
    System.out.println(  re.read());
    System.out.println(  re.read());
    System.out.println(  re.read());
    System.out.println(  re.read());
    System.out.println(  re.read());
    System.out.println(  re.read());

    System.out.println("=====================依靠循环来读取===================");
//这里不用wi的原因是因为wi已经读取了部分数据了,接下来只会从未读取的部分开始读取

//    此时代表以一个字符数组为单位进行读取
    char[] chars=new char[20];

    int num;
    while((num=re2.read(chars))!=-1){
//        num是每次读取到的字符的长度  因为是字符流单位是字符  一个字符三个字节,不常用四个字节 在utf-8编码格式下
//        中长度设置的是20,但是一共只有15个字符,所以num打印为15
        System.out.println(num);
        System.out.println(chars);
//        把读取到的集合转化为一个字符串
        System.out.println(new String(chars,0,num));
    }

字符输出流

随意准备一个又内容的文档:

代码如下:
 

  public static void main(String[] args) throws IOException {
        Writer wi=new FileWriter("src/com/haogu/Java04/wirte1.txt");
        wi.write("第二次输入的数据,完成覆盖初始数据");
//    todo 重点我们会发现,如果我们不去关闭这个流,那么数据不会被写入文件,会一直保存在缓冲区内部
//        所以在操作字符流的时候,最后书写完毕之后一定记得关闭流
        wi.close();
//        在文件本来原有的内容上添加而不是去覆盖
        Writer wi2=new FileWriter("src/com/haogu/Java04/wirte1.txt",true);
        wi2.write("{中括号内是添加的内容}");
        wi2.close();
    }

 运行后的结果变为

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值