应该是很多人的技术盲点,用io流复制一个文件,通过int变量赋值可以成功读出,但是读取方法直接调用读入方法返回的参数却不能成功读出

代码如下:

package com.test.file_1;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Scanner;
//用来复制文件
public class Test_iofile92 {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        /*
         * 1.输入要复制的路径,输入要输出的路径
         * 2.根据路径读取数据
         *  2.1,新建读取对象
         *  2.2,读取
         *  2.3,释放资源
         * 3.根据路径输出数据
         *    3.1新建输出对象
         *    3.2输出
         *    3.3释放资源
         *
         */
        System.out.println("输入需要复制的文件路径:");
        String in =new Scanner(System.in).nextLine();
        System.out.println("输入需要输出的文件路径:");
        String out =new Scanner(System.in).nextLine();
        File ain = new File(in);
        File bout = new File(out);
        read12(ain,bout);
    }
    private static void read12(File ain,File bout) {
        InputStream ain1 =null;
        OutputStream bout1 =null;
        try {
            ain1 = new BufferedInputStream(new FileInputStream(ain));
            bout1 = new BufferedOutputStream(new FileOutputStream(bout));



**//            int b = 0;
//            while((b=ain1.read())!=-1) {    
//                bout1.write(b);
//            }**


        while(ain1.read()!=-1) {
                bout1.write(ain1.read());


            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            try {
                ain1.close();
                bout1.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

这种情况输出的文件是有乱码的,但是把

**//            int b = 0;
//            while((b=ain1.read())!=-1) {    
//                bout1.write(b);
//            }**

这边的注释拿掉,并且把下面的代码注释掉,程序就能够正常输出,这是为什么
img

while(ain1.read()!=-1) {
                bout1.write(ain1.read());


            }

img

IO流初学者最常见的问题,就是在循环的控制条件中调用的read()也会使流的位置改变,所以必须用赋值把读入的数据保存起来才能防止丢失
中文汉字一般为2个字节,而read方法读一个字节,你第二种代码写法会在判断循环读入一字节,然后写入第二字节,相当于只写了每个汉字的第二字节,这些字节重新拼接起来自然乱码