字节流分为两种:InputStream(输入字节流)、OutputStream(输出字节流);
如何区分是该用InputStream,还是OutputStream:
从某个文件中读取数据到终端中用InputStream;终端向某个文件中输入数据用OutputStream;而这个终端在写代码时,可以理解为:你写代码时所用的这个软件界面;
InputStream对象从文件中读取数据的方法是read,OutputStream对象向文件中输入数据的方法是write;

InputStream的**read()**方法:

public class InputAndOut {
    public static  void FileToFile1(String path1,String path2){
        File file1=new File(path1);
        File file2=new File(path2);
        FileInputStream in=null;
        FileOutputStream out=null;
        try {
            in=new FileInputStream(file1);
            out=new FileOutputStream(file2);
            int value=-1;
            while((value=in.read())!=-1){/*当file1中有数据可读时,读出的数据赋值给value,当没有数据可读时,返回-1*/
                out.write(value);/*就将从file1文件中读出的数据写入file2中*/
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            /*要记得关闭数据流*/
            if(in!=null){
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(out!=null){

                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    } 
}

InputStream的**read(byte b[])**方法:每次从文件中读取b.size()个大小的数据存放在b中;该方法返回的是读取数据的长度,将读取的数据存放在b中;当无数据可读时返回-1;
上面中try{}内部的内容可以用以下代码代替

in=new FileInputStream(file1);
            out=new FileOutputStream(file2);
           int len=-1;
            /*读取数据,也可以不一个一个字节的读取,可以使用缓存方式读取和写入*/
            byte[] buff=new byte[3];//当然可以写为1024
            while((len=in.read(buff))!=-1){/*每次读取3个字节存放在buff中,返回的len是读取的数据的长度*/
                out.write(buff);/*将buff中的数据写入file2中*/

或者是**read(byte b[],int off,int len)**方法:
off代表起始位置,len代表长度;

in=new FileInputStream(file1);
            out=new FileOutputStream(file2);
            int len=-1;
            /*读取数据,也可以不一个一个字节的读取,可以使用缓存方式读取和写入*/
            byte[] buff=new byte[3];//当然可以写为1024
            while((len=in.read(buff))!=-1){/*每次读取3个字节存放在buff中,返回的len是读取的数据的长度*/
                out.write(buff,0,len);/*将buff中的从[0,len)之间的数据写入file2中*/

OutputStream的write()方法,括号中参数也是很多的:

FileOutputStream out=null;
            out=new FileOutputStream(file);
            out.write(1);//int型
            out.write('A');//byte型
            byte[] bytes=new byte[]{'a','b','c','d'};
            out.write(bytes);//byte[]型
            out.write(bytes,1,3);//byte[]某个范围中[1,3)之间的数据

OutputStream还继承了AutoCloseable接口,可以自动关闭字节流:

public abstract class OutputStream implements Closeable, Flushable

InputStream还继承了Closeable接口,而Closeable接口又继承了AutoCloseable,所以InputStream也是可以自动关闭字节流的:

public abstract class InputStream implements Closeable
public interface Closeable extends AutoCloseable

继承了AutoCloseable接口的类是怎么实现的呢:

//继承了AutoCloseable 接口的类
public class AutoClose implements  AutoCloseable {

    public void print(){

        System.out.println("打印");
    }
    @Override
    public void close() throws Exception {
        System.out.println("打印完毕");
    }
    public static void main(String[] args) {
         AutoClose autoClose=new AutoClose();
         autoClose.print();
        try {
            autoClose.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println("++++++++++++++++++++++++");
        //但是,如果将AutoClose创建对象的过程放在try()括号中,则clos会自动调用
        try(AutoClose p=new AutoClose()){
            p.print();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

结果:

Android outputStream 和 inputStream 写入文件_数据


从而可以发现继承了AutoCloseable 接口的类是可以自动关闭流的,只是要将创建对象的过程放在try()中;

所以:

File infile = new File("D:/test/input.txt");
        File outfile = new File("D:/test/output.txt");
        /*将输入流、输出流的创建过程写在try()内,中间用;隔开*/
        try (InputStream in = new FileInputStream(infile);
             OutputStream out = new FileOutputStream(outfile)) {

            int value=-1;
            while((value=in.read())!=-1) {
                out.write(value);

            }
            out.write(new byte[]{'a', 'b', 'c'});
        } catch (IOException e) {
            e.printStackTrace();
        }

但是,这样子会造成混乱,不知道到底关闭流了没,所以不建议这样使用,还是自己手动关闭流比较好;