IO流操作

1.1基于数组操作的流

ByteArrayInputStream可以基于字节数组创建输入流

构造方法:

//创建一个带有缓冲字节数据的字节数组输出流

 ByteArrayInputStream(byte[] buf);

//创建一个带有缓冲字节数据的字节数组输出流

 ByteArrayInputStream(byte[] buf,int off,int len);

主要方法:

int read();//返回此输入流的下一个字节

int read(byte []b,intvoff,int len);//将输入流中的len个字节如入到字节数组b中。

ByteArrayOutputStream:可以把数据输出字节数组中

构造方法:

  ByteArrayOutputStream();

  ByteArratOutputStream(int size);//创建一个指定缓冲区大小的字节数组输出流。

主要方法:

 String toString();//使用平台默认的字符集,通过解码字节将缓冲区内容转换为字符串。

 void write(int ch);//将该字节写入到输出流中。

 void write(byte[]b,int off,int length);//将该字节数组b,length个字节写入到该输出流中。
 

代码如下:

   输入:


    @Test
    /**
     * ByteArrayInputStream可以基于字节数组创建输入流
     */
    public void test1() throws IOException {
        byte[] arr={97,98,99,100,101,102};
         ByteArrayInputStream in = new ByteArrayInputStream(arr);
         int length = -1;
         byte[] buffer = new byte[3];
         while ((length=in.read(buffer))!=-1){
             System.out.println(Arrays.toString(buffer));
         }
    }

结果演示: 

 输出:

  @Test
    /**
     * ByteArrayOutputStream:可以把数据输出字节数组中
     */
public void test2() throws Exception {
        BufferedInputStream in = new BufferedInputStream(new FileInputStream("hello.txt"));
        ByteArrayOutputStream out = new ByteArrayOutputStream();

        int length = -1;
        byte[] buffer = new byte[5];
        while ((length=in.read(buffer))!=-1){
            out.write(buffer,0,length);
        }

        byte[] data = out.toByteArray();//得到输出字符数组
        in.close();
        out.close();
        System.out.println(Arrays.toString(data));
    }

结果演示: 

 扩:CharArrayReader:基于字符数组产生输入流,CharArrayWriter:输出到字节数组中的输出流,其方法与上例相似

1.2数据流

  • 为了方便地操作Java语言的基本数据类型和String的数据,可以使用数据流。
  • 数据流有两个类: (用于读取和写出基本数据类型、 String类的数据)
    • DataInputStream 和 DataOutputStream
    • 分别“套接”在 InputStream 和 OutputStream 子类的流上
  • DataInputStream中的方法
    • boolean readBoolean()
    • byte readByte()
    • char readChar()
    • float readFloat()
    • double readDouble()
    • short readShort()
    • long readLong()
    • int readInt()
    • String readUTF()
    • void readFully(byte[] b)
  • DataOutputStream中的方法
    • 将上述的方法的read改为相应的write即可

代码示例:

正确输出:

 注意:write与read相对对应,否则会出现输出异常

  代码最后要关闭输入输出流close();

据输入流和输出流以机器无关的方式进行写入和读取数据,实际上数据输出流是将java的基本类型,底层存储的时候以字节形式进行存储.而数据输入流读取后数据后,会将字节的进行拼接.得到java基本类型

注意:UTF-8是1-4个字节可变的;GBK是1~2个字节

1.3PrintStream方法


 编写代码报错时,我们可以通过PrintStream方法编写日志,方便查找错误

PrintStream特点:

1. 只负责输出,不负责数据的读取

2. 与其他输出流不同,printStream永远不会抛出IOException

3. 有特有的方法

1. PrintStream(File file):输出的目的地是一个文件

2. PrintStream(OutputStream out):输出的目的地是一个字节流

3. PrintStream(String fileName):输出的目的地是文件路径

PrintStream extends OutputStream,继承自父类的成员方法:

1.public void close():关闭此输出流并释放此流相关联的任何系统资源

2.public void flush():刷新此流并强制任何缓冲流的输出字节被写出。

3.public void write(byte[] b):将b.Length字节从指定的字节写入此输出流。

4.public void write(byte[] b,int off,int len):从指定的字节数组写入len字节,从偏移量off开始输出到此输出流。

5. public abstract void write(int b):将指定的字节流输出

 String s=null;
 String s1 = s.toString();
 System.out.println(s1);//空指针


编译后:
Exception in thread "main" java.lang.NullPointerException
at com.lina.test.e_printStream.test1.main(test1.java:6)

改写:

  public static void main(String[] args) throws FileNotFoundException {
        try {
            String s=null;
            s.toString();//空指针异常
        } catch (Exception e) {
            //e.printStackTrace();
            PrintStream writer = new PrintStream("logo.txt");
             SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
           writer.println(sf.format(new Date())+":"+e.getMessage());
            writer.close();
        }
    }

 2023-08-14 06:58:55:null                在log里打印错误

1.4对象流 

  1. 介绍        

        用于存储和读取基本数据类型数据或对象的处理流。它的强大之处就是可以把Java中的对象写入到文件源中(序列化),也能把对象从文件源中还原回来(反序列化

    2.序列化机制

        对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从
而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传
输到另一个网络节点。
当其它程序获取了这种二进制流,就可以恢复成原来的Java对象

序列化:用ObjectOutputStream类保存基本类型数据或对象的机制
反序列化:用ObjectInputStream类读取基本类型数据或对象的机制

注意:ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量

 3.序列化好处

可将任何实现了Serializable接口的对象转化为字节数据,使其在保存和传输时可被还原

4.注意

        首先,如果需要让某个对象支持序列化机制,则必须让对象所属的类及其属性是可
序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口之一。

  1. Serializable(主要实现这个接口)
  2. Externalizable

对象流使用时,自定义对象必须实现Serializable接口,否则会抛出java.io.NotSerializableException

凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量:

1、确保不同版本有不同的UID
2、序列化一个类实例,更改一个字段或者添加一个字段,不设置UID,任何更改导致无法反序列化实例,并抛出异常,如果添加UID,反序列化旧实例,新增加或者 更改字段被设为初始值,对象为null


 private static final long serialVersionUID = 1755878437777619416L;

image.png

5.步骤

使用对象节点流序列化

1. 创建节点输出流(FileOutputStream)
2. 创建对象流(ObjectOutputStream)
3. 调用 ObjectOutputStream 对象的 writeObject(对象) 方法输出可序列化对象
4. 关闭流close

 public void test1() throws Exception {
        User user = new User(18,"l","China");
         ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("user"));
         out.writeObject(user);
         out.close();
    System.out.println(user);
    }

 输出序列化对象后,需要进行反序列化操作才能得到内容!否则乱码!

使用对象反序列化

1. 创建节点输出流(FileInputStream)

2. 创建对象流(ObjectInputStream)

3. 调用 ObjectOutputStream 对象的 readObject() 方法输出可序列化对象

4. 关闭流

 public void test2() throws Exception {
         ObjectInputStream in = new ObjectInputStream(new FileInputStream("user"));
         User user = (User) in.readObject();
        System.out.println(user);
        in.close();
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高级的南松

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值