java IO字节流

目录

IO流概述及其分类

概念

IO流常用父类

IO流程序书写:

FileInputStream

read()方法的返回值为什么是int而不是byte

FileOutputStream

拷贝图片

字节数组拷贝之available()方法

定义小数组

定义小数组的标准格式

BufferedInputStream和BufferOutStream

flush和close方法的区别

字节流读写中文 

流的标准处理异常 

图片加密

拷贝文件

录入数据拷贝到文件


 

IO流概述及其分类

概念

  • IO流用来处理设备之间的数据传输
  • Java对数据的操作是通过流的方式z
  • 流按流向分为两种:输入流,输出流
  • 流按照操作类型分为两种
    • 字节流:字节流可以操作任何数据,因为在计算机中任何数据都是以字节的形式存储的
    • 字符类:字符流只能操作纯字符数据,比较方便

IO流常用父类

字节流的抽象父类

  • InputStream
  • OutputStream

字符流的抽象父类

  • Reader
  • Writer

IO流程序书写:

使用前:导入IO包中的类

使用时:将进行IO异常处理

使用后:释放资源

FileInputStream

注意:博主在当前项目下创建了xxx.txt文件里面存储的是abc

import javimport java.io.FileInputStream;
import java.io.IOException;

public class demo {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("xxx.txt"); //创建流对象
        int x = fis.read();   //从硬盘上读取一个字节
        System.out.println(x);

        int y = fis.read();
        System.out.println(y);

        int z = fis.read();
        System.out.println(z);

        int a = fis.read();
        System.out.println(a);
        fis.close();   //关流释放资源
    }
}

输出结果为

 由此可见当程序读到-1时文件已经读取完毕因此可以修改代码如下

import java.io.FileInputStream;
import java.io.IOException;

public class demo {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("xxx.txt"); //创建流对象
        int b;
        while((b = fis.read()) != -1){
            System.out.println(b);
        }
        fis.close();   //关流释放资源
    }
}

read()方法的返回值为什么是int而不是byte

 由于byte类型运算时是利用补码运算的因此读到11111111是-1的补码,因此遇到11111111读取就会停止,后面的数据就读不到了,所以在读取的时候用int类型接收,如果11111111会在前面补上24个0,byte类型的-1就变成int类型的255l,这样就可以保证程序完整读完

FileOutputStream

在创建对象时如果没有这个文件就创建文件,如果有这个文件就先清空文件内容


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

class demo2 {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("yyy.txt");  //创建字节输出流对象,如果没有就自己创建一个
        fos.write(97); //虽然写出的是一个int数但是到文件上是一个字节会自动去除前三个8位
        fos.write(98);
        
        fos.close();
    }
}

FileOutputStream的构造方法写出数据如何实现数据的追加写入

 

import java.io.FileOutputStream;
import java.io.IOException;

public class demo4 {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("yyy.txt",true); //如果想续写就在第二个参数传true
        fos.write(97);
    }
}

拷贝图片

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class demo5 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("i.JPG");
        FileOutputStream fos = new FileOutputStream("copy.jpg");

        int b ;
        while((b=fis.read()) != -1) {
            fos.write(b);
        }
        fis.close();
        fos.close();
    }
}

但是拷贝过大的文件效率过慢,因此开发中不推荐使用

字节数组拷贝之available()方法

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class demo5 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("i.JPG");
        FileOutputStream fos = new FileOutputStream("copy.jpg");
//        int len = fis.available();
//        System.out.println(len);
        byte[] arr = new byte[fis.available()];  //创建与文件相同大小的数组
        fis.read(arr);   //将文件上的字节读取到内存中 
        fos.write(arr);  //将字节数组中的字节数据写到文件上

        fis.close();
        fos.close();
    }
}

但是开发中不推荐这种方法,因为有可能导致内存溢出

定义小数组

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class demo6 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("xxx.txt");
        FileOutputStream fos = new FileOutputStream("yyy.txt");
        byte[] arr = new byte[2];
        int len;     //len为读到的有效字节个数
        while((len = fis.read(arr)) != -1){
            fos.write(arr,0,len);
        }
        fis.close();
        fos.close();
    }
}

定义小数组的标准格式

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class demo6 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("xxx.txt");
        FileOutputStream fos = new FileOutputStream("yyy.txt");
        byte[] arr = new byte[1024 * 8];   //8k
        int len;     //len为读到的有效字节个数
        while((len = fis.read(arr)) != -1){  //如果忘记加arr返回的不是字节个数而是码表值
            fos.write(arr,0,len);
        }
        fis.close();
        fos.close();
    }
}

BufferedInputStream和BufferOutStream

import java.io.*;

public class demo7 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("xxx.txt");  //创建输入流对象,关联xxx.txt
        FileOutputStream fos = new FileOutputStream("yyy.txt"); //创建输出流对象,关联yyy.txt
        BufferedInputStream bis = new BufferedInputStream(fis);  //创建缓冲区对象,对输入流进行包装使其更强大
        BufferedOutputStream bos = new BufferedOutputStream(fos); //创建缓冲区对象,对输出流进行包装使其更强大

        int b;
        while ((b = bis.read())!=-1) {
            bos.write(b);
        }
        bis.close();
        bos.close();
    }
}

原理图

 缓冲思想:

        字节流一次读写一个数组的速度明显比一次读一个字节的速度快很多

        这是加入了数组这样的缓冲区效果,java本身在设计的时候也考虑到了这样的设计思想(装饰设计模式)所以提供了字节缓冲区流

BufferedInputStream

        BufferedInputStream内置了一个缓冲区数组,从其中读取一个字节时,它会一次性从文件中读取8192个,存在缓冲区中,返回给程序一个,程序再次读取时,就不用找文件了,直接从缓冲区中读取,直到缓冲区中的所有都被使用过,才重新从文件中读取8192个

BufferOutputStream

        BufferOutputStream也内置了一个缓冲区数组,程序想流中写出字节时,不会直接写出文件,先写到缓冲区,直到缓冲区写满,他才把程序一次性写到文件里面

 小数组读写和带Buffered的读取哪个更快

        定义小数组如果是8192个字节大小和Buffered比较的话,定义小数组会略胜一筹,因为读和写操作的是同一组数组,而Buffered操作的是两个数组

flush和close方法的区别

flush()方法

        用来刷新缓冲区的刷新后可以再次写出

close()方法

        用来关闭流释放资源的,如果是带缓冲区的流对象的close()方法,不但会关闭流,还会再关闭流之前刷新缓冲区,将缓冲区的字节全都刷新到文件上,关闭后不能再写出

字节流读写中文 

字节流读取中文的问题

        字节流在读中文时读到半个中文,可能出现乱码

字节写中文的问题

        字节流直接操作的字节,所以写出中文必须将字符串转换成字节数组

        写出回车换行write("\r\n".getBytes())

流的标准处理异常 

JDK1.6及以前的处理方法

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class demo6 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream("xxx.txt");
            fos = new FileOutputStream("yyy.txt");
            byte[] arr = new byte[1024 * 8];   //8k
            int len;     //len为读到的有效字节个数
            while ((len = fis.read(arr)) != -1) {  //如果忘记加arr返回的不是字节个数而是码表值
                fos.write(arr, 0, len);
            }
        }
        finally {
            try {
                if (fis != null) {
                    fis.close();
                }
            }finally{                   //嵌套目的是能关一个尽量关一个
                if(fos != null) {
                    fos.close();
                 }
            }
        }
    }
}

JDK1.7的处理方法

执行完会自己关闭

import java.io.*;

public class demo7 {
    public static void main(String[] args) throws IOException {
        try(
            FileInputStream fis = new FileInputStream("xxx.txt");  //创建输入流对象,关联xxx.txt
            FileOutputStream fos = new FileOutputStream("yyy.txt"); //创建输出流对象,关联yyy.txt
        ){
            int b;
            while ((b = fis.read()) != -1) {
                fos.write(b);
            }
        }
    }
}

图片加密

import java.io.*;

public class test {
    public static void main(String[] args) throws IOException {
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("w.jpg"));
        BufferedOutputStream bos  = new BufferedOutputStream(new FileOutputStream("y.jpg"));
        int b;
        while((b = bis.read()) != -1) {
            bos.write(b ^ 123);
        }
        bis.close();
        bos.close();
    }
}

一个数与同一个数异或两次等于它本身

拷贝文件

import java.io.*;
import java.util.Scanner;

public class test2 {
    public static void main(String[] args) throws IOException {
        File file = getFile();
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file.getName()));     //源文件名
        int b;
        while((b=bis.read())!=-1) {
            bos.write(b);
        }
        bis.close();
        bos.close();

    }

    public static File getFile(){ //判断文件路径是文件之后再返回
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入文件路径:");

        while(true) {
            String s = sc.nextLine();
            File file = new File(s);
            if(!file.exists()) {
                System.out.println("您输入的路径不存在,请重新输入:");
            }else if(file.isDirectory()) {
                System.out.println("您输入的是文件夹路径请重新输入:");
            }else {
                return file;
            }
        }
    }
}

录入数据拷贝到文件

mport java.io.FileOutputStream;
import java.io.IOException;

import java.util.Scanner;
public class test3 {
    public static void main(String[] args) throws IOException, IOException {
        Scanner sc = new Scanner(System.in);
        FileOutputStream fos = new FileOutputStream("test.txt");
        while(true){
            String s = sc.nextLine();
            if("quit".equals(s)){
                break;
            }
            fos.write(s.getBytes());
            fos.write("\r\n".getBytes());
        }
        fos.close();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值