字节数组与字节流、缓冲字节流、字符流、缓冲字符流、对象流

本文介绍了Java中字节流与字符流的使用,包括字节数组的读写、Buffered流的缓冲功能、字符流的Reader/Writer及其包装类BufferedReader和PrintWriter的使用。同时,详细讲解了对象输入输出流在序列化和反序列化中的应用,以及JavaBean的设计规范。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一。字节流
1.读写字节数组

 public void copy1() throws IOException {
        InputStream in=new FileInputStream("a.txt");
        OutputStream ot=new FileOutputStream("a.txt");
        OutputStream ot1=new FileOutputStream("d.txt");
        //创建字符串写入
        String str="你好,世界";
        byte[] bs=str.getBytes();//将字符串编码为字节数组
        System.out.println("写入的字符长度:"+bs.length);
        int len;
        ot.write(bs,0,bs.length);//写入全部
        ot.write(bs,3,3);//写入index2开始,2字节长度。写入‘好’
        //读取
        byte[] b=new byte[4];//定义单次读取字节的长度为4
//        while ((len=in.read(b))!=-1){//in.read(b)返回的是in从ot读来的长度
//            //System.out.println(new String(b));
//            /*这样打印读取若bs.length和b.length不是倍数关系,最后一次读取会出现问题
//            因为byte[] b每次传入相当于都被重写,最后一次重写两个数组长度不一样,不能实现全部的字节覆盖
//             */
//            System.out.println("len"+len);
//            System.out.println(Arrays.toString(b));
//            ot1.write(b);//写入结果:你好,世界好��。最后一次没完全覆盖b,所以有乱码
//        }
        System.out.println("______________________-");
        //读取2
        while ((len=in.read(b))!=-1){
            System.out.println("len"+len);
            //System.out.println(new String(b,0,len));
            System.out.println(Arrays.toString(b));
            ot1.write(b,0,len);//写入结果:你好,世界好
        }
    }

2.包装 -> 高级流: BufferedInputStream/BufferedOutputStream
Buffered: 缓冲/缓存
①缓冲流读取大文件

public class copy2 {
    @Test
    public void copy() throws IOException {
        //缓冲流读写大文件快
        // 缓冲流是用字节流来包装的
        BufferedInputStream buin = new BufferedInputStream(new FileInputStream("dx.png"));
        BufferedOutputStream buot = new BufferedOutputStream(new FileOutputStream("dx_副本.png"));
        byte[] a = new byte[1024];
        int len;
        while ((len = buin.read(a)) != -1) {
            buot.write(a, 0, len);
        }
        //手动刷新缓冲区(当度的文件太小,导致缓冲区不能填满时会造成写入的不显示问题,要手动将缓冲区剩余内容写入)
        //buot.flush();
        buin.close();//关闭流的时候也会自动刷新缓冲区内容
        buot.close();
    }

②用异或加密

  @Test
    public void copy1() throws IOException {
        /*异或:相同为0,不同为1
          0001 1101
         ^0011 1011
     等于:0010 0110
         ^0011 1011
     等于:0001 1101
         */
        //文件赋值过程加密和解密
        BufferedInputStream buin = new BufferedInputStream(new FileInputStream("a.txt"));
        BufferedOutputStream buot = new BufferedOutputStream(new FileOutputStream("d.txt"));
        BufferedInputStream buin1 = new BufferedInputStream(new FileInputStream("d.txt"));
        BufferedOutputStream buot1 = new BufferedOutputStream(new FileOutputStream("c.txt"));

        int i;
        while ((i = buin.read()) != -1) {
            //加密
            buot.write(i ^ 1);
        }
        buin.close();//关闭流的时候也会自动刷新缓冲区内容
        buot.close();
        int c;
        while ((c = buin1.read()) != -1) {
            //解密
            buot1.write(c ^ 1);
        }
        buin1.close();
        buot1.close();
    }

③ try catch抓取
需要将关闭流放在finally里

方式一
@Test
    public void trycatch() {
        BufferedInputStream buin = null;
        BufferedOutputStream buot = null;

        try {
            buin=new BufferedInputStream(new FileInputStream("a.txt"));
            buot=new BufferedOutputStream(new FileOutputStream("d.txt"));
            int i;
            while ((i = buin.read()) != -1){
                buot.write(i);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {//在finall中关闭流
            if(buin!=null){
                try {
                    buin.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(buot!=null){
                try {
                    buot.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    --------------------------------------------------------
    方式二
    @Test
    public void tryCatchTest() {
        // try(resource) {} 不管有没有异常, resource都会自动关闭, 不需要finally
        try(BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a_bak.txt"));
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("a_bak_back.txt"))) {
            int a ;
            while ((a = bis.read()) != -1) {
                bos.write(a ^ 1);
            }            
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

二。字符流
1.字符流
Reader/Writer
InputStreamReader(InputStream in, String charsetName) - 指定字符集
InputStreamReader(InputStream in) - 默认字符集
int read() 读一个字符
int read(char[] cbuf) 将字符读入数组。
int read(char[] cbuf, int off, int len) 将字符读入数组的一部分。- 了解
注: 以上三个方法, 返回 -1 都标记着读到文件末尾

OutputStreamWriter(OutputStream out, String charsetName)
OutputStreamWriter(OutputStream out)
    void write(char[] cbuf) 写入一个字符数组。
    void write(char[] cbuf, int off, int len) 写入字符数组的一部分。
    void write(int c) 写入单个字符
@Test
    public void zifu1() throws IOException {
        Writer w=new OutputStreamWriter(new FileOutputStream("a.txt"));
        Reader r=new InputStreamReader(new FileInputStream("a.txt"));
        Writer w1=new OutputStreamWriter(new FileOutputStream("d.txt"));
        //写字符
        w.write('c');
        w.write(97);
        w.write("dcc");
        w.write("你好");
        w.write('\n');
        char[] ch={'h','i','o','k','尼'};
        w.write(ch,1,4);
        w.write('\n');
        String str="我是好人";
        w.write(str,1,3);
        w.close();
        //读字符
        char[] m=new char[20];
        int len;
        //①
        while ((len=r.read(m))!=-1){
            w1.write(m);//字符写,m最后一次重写有多余的没事,因为空白字符写进去也是空白字符
            System.out.println(Arrays.toString(m));
        }
       //②
        while ((len=r.read(m))!=-1){
            w1.write(m,0,len);
            System.out.println(Arrays.toString(m));
        }
        //③
        int i;
        while ((i=r.read())!=-1){
            w1.write(i);
            System.out.println(i);
        }
        w1.write("\n换行");
        w1.close();
    }
    @Test
    public void zifu2() throws IOException {
        Writer w=new OutputStreamWriter(new FileOutputStream("a.txt"));
        Reader r=new InputStreamReader(new FileInputStream("a.txt"));
        Writer w1=new OutputStreamWriter(new FileOutputStream("d.txt"));
        //文件复制
       w.write("火云邪神差点杀了我QAQ");
       w.close();
       int i;
       while((i=r.read())!=-1){
           w1.write(i);
       }
       w1.close();
    }

2.包装字符流 -> 缓冲字符流
通常用来读写文件内容
BufferedReader(Reader)
String readLine(): 读取一整行, 返回null 标记读到文件末尾
PrintWriter
1.只能清空原文件内容, 但是可以指定字符集
PrintWriter(String fileName, String csn)
2.可以在原文件上追加内容, 但是不可以指定字符集, 可以自动刷新缓冲区
PrintWriter(OutputStream out, boolean autoFlush)
3.可以在原文件上追加内容, 可以指定字符集, 可以自动刷新缓冲区
PrintWriter(Writer out, boolean autoFlush)

    void print(Object): 写出内容, 不加换行
    void println(): 写出内容, 并且换行
    注意: 自动刷新的功能, 只有println方法具有
          print方法 必须手动刷新
 @Test
    public void buff() throws IOException {
        //字符缓冲流读
        BufferedReader red = new BufferedReader(
                new InputStreamReader(
                        new FileInputStream("a.txt")));
        String str;
        while ((str = red.readLine()) != null) {//读一整行。
            System.out.println(str);
        }
        red.close();
    }

    @Test
    public void print() throws FileNotFoundException {
        //字符缓冲流写打印
        PrintWriter pt = new PrintWriter(
                new OutputStreamWriter(//字节流后true可接着写;字符流true,自动缓冲flash;
                        new FileOutputStream("d.txt",true)),true);
        pt.print("我是太阳");
        pt.print("喜喜");
        pt.print("\n");
        pt.write("ddd");
        pt.println("fffff");//只有以pt.println结尾才会触发自动缓冲flash的true。否则需要手动flash
    }
    @Test
    public void copy() throws IOException {
       BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream("d.txt")));
       PrintWriter pw=new PrintWriter(new OutputStreamWriter(new FileOutputStream("d.txt",true)),true);
       PrintWriter pw1=new PrintWriter(new OutputStreamWriter(new FileOutputStream("a.txt",true)),true);
       pw.write("一闪一闪亮晶晶");
       pw.print("满天都是小行星");
       pw.println("看星星");
       pw.println("跑商跑商跑商跑商跑商视频");
       String i;
       while ((i=br.readLine())!=null){
           pw1.println(i);
       }
    }

三。对象输入输出流:
对象 -> 文件[字节] : 序列化
文件[字节] -> 对象 : 反序列化

ObjectInputStream(InputStream)
    Object readObject()
ObjectOutputStream(OutputStream)
    void writeObject(Object)
Serializable: 可序列化的
    接口中没有常量, 也没有抽象方法, 空接口
    序列化接口没有方法或字段,仅用于标识可串行化的语义。

serialVersionUID: 给类添加固定的序列版本号
transient: 修饰的变量, 在序列化的时候, 会被忽略掉
public class Studeng implements Serializable {//Serializable接口,有序化的
    //类会自己生成一个版号,但内容改变也会改变
    //所以手动生成一个序列版号
    public static  final long serialVersionUID =1234l;
    int age;
    String name;
    transient char  sex;//transient 修饰的在序列化时他的只会被忽视.


    public Studeng(String name, char sex, int age){
        this.name=name;
        this.age=age;
        this.sex=sex;
    }

    @Override
    public String toString() {
        return
                age +
                "," + name +
                "," + sex ;
    }
//get/set
...
}
------------------------------------------
@Test
    public void stu() throws IOException, ClassNotFoundException {
        //创建序列化流
        ObjectOutput ot=new ObjectOutputStream(new FileOutputStream("a.txt"));
        //创建反序列化流
        ObjectInput in=new ObjectInputStream(new FileInputStream("a.txt"));
        //写出对象
        Studeng m=new Studeng("王贵",'男',13);
        ot.writeObject(m);
        ot.close();
        //读取对象
        Studeng x=(Studeng) in.readObject();
        System.out.println(x);

    }

四。JavaBean规范:
1.所有成员变量私有化, 并且提供get/set方法
2.必须要有空参构造方法
3.基本数据类型建议使用包装类
4.实现 Serializable 接口
5.重写 equals, hashCode, toString 方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值