数据流
数据输入流: 此流最大的特点是能够读写基本数据类型
DataInputStream
数据输出流:
DataOutputStream
怎么写的你就怎么读取,顺序不要乱
package demo2;
import java.io.*;
//数据输入流
public class Test {
public static void main(String[] args) throws IOException {
DataOutputStream out=new DataOutputStream(new FileOutputStream("F:\\JavaTxt\\b.txt"));
DataInputStream in=new DataInputStream(new FileInputStream("F:\\JavaTxt\\b.txt"));
out.writeInt(90);
out.flush();
out.writeDouble(3.14);
out.flush();
out.writeBoolean(true);
out.flush();
out.writeByte('a');
out.flush();
out.writeUTF("你好java");
System.out.println("读整数:"+in.readInt());
System.out.println("读小数:"+in.readDouble());
System.out.println("读读布尔类型:"+in.readBoolean());
System.out.println("读字节类型:"+in.readByte());
System.out.println("读字符串:"+in.readUTF());
}
}
运行结果:
读整数:90
读小数:3.14
读读布尔类型:true
读字节类型:97
读字符串:你好java
内存操作流
操作字节数组
-
ByteArrayOutputStream ByteArrayInputStream
此流关闭无效,所以无需关闭
操作字符数组
- CharArrayWrite CharArrayReader
操作字符串
- StringWriter StringReader
内存操作流,在内存中进行数据的读写,并不直接去关联文件
- ByteArrayOutputStream ByteArrayInputStream
此类实现了一个输出流,其中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。
可使用 toByteArray () 和 toString () 获取数据
关闭 ByteArrayOutputStream 无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException。
ByteArrayOutputStream()
ByteArrayOutputStream() 创建一个新的 byte 数组输出流。
ByteArrayOutputStream 他自己在内存中维护了一个字节数组,充当缓冲区,会把数据不断的写入到缓冲区
打印流
打印流的特点:
打印流只能操作目的地,不能操作数据源(不能进行读取数据)
可以操作任意数据类型的数据 调用print() 方法可以写任意数据类型
如果我们启用自动刷新,那么在调用println、printf 或 format 方法中的一个方法的时候,会完成自动刷新
方法:
- PrintWriter(OutputStream out, boolean autoFlush):根据现有的OutputStream创建新的PrintWrite。当autoFlush为true时,此输入流会自动刷新
- PrintWriter(Writer out, boolean autoFlush) :创建新的PrintWrite。当autoFlush为true时,此输入流会自动刷新
- public void print(String s) :打印字符串
- public void println(String x):打印字符串,并自动换行 标准输入输出流
标准输入输出流概述
public static final InputStream in: 标准输入流, 对应的设备是键盘
public static final PrintStream out: 标准输出流 , 对应的设备就是显示器
随机访问流
随机访问流概述
RandomAccessFile概述 最大特点 能读能写
RandomAccessFile类不属于流,是Object类的子类。但它融合了InputStream和OutputStream的功能。
支持对随机访问文件的读取和写入。
RandomAccessFile的父类是Object , 这个流对象可以用来读取数据也可以用来写数据.可以操作任意数据类型的数据.
我们可以通过getFilePointer方法获取文件指针,并且可以通过seek方法设置文件指针
package demo3;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.file.Path;
//RandomAccessFile
public class Test5 {
public static void main(String[] args) throws IOException {
Path path;
RandomAccessFile raf=new RandomAccessFile("F:\\JavaTxt\\e.txt", "rw");
raf.writeInt(234);
raf.writeUTF("你好JAVA");
raf.writeBoolean(true);
raf.writeByte('a');
System.out.println("=========================================");
RandomAccessFile ra=new RandomAccessFile("F:\\JavaTxt\\e.txt", "rw");
int a=ra.readInt();
System.out.println("文件位置:"+ra.getFilePointer());
System.out.println("整数:"+a);
String b=ra.readUTF();
System.out.println("文件位置:"+ra.getFilePointer());
System.out.println("字符串:"+b);
Boolean c=ra.readBoolean();
System.out.println("文件位置:"+ra.getFilePointer());
System.out.println("布尔:"+c);
Byte d=ra.readByte();
System.out.println("文件位置:"+ra.getFilePointer());
System.out.println("字节:"+d);
ra.seek(16);//设置指针位置
System.out.println(ra.readBoolean());
}
}
运行结果:
=========================================
文件位置:4
整数:234
文件位置:16
字符串:你好JAVA
文件位置:17
布尔:true
文件位置:18
字节:97
true
序列化流
序列化:把对象转换为字节序列的过程称为对象的序列化.
反序列化:把字节序列恢复为对象的过程称为对象的反序列化.
序列化流的概述
所谓的序列化:就是把对象通过流的方式存储到文件中.注意:此对象 要重写Serializable 接口才能被序列化
反序列化:就是把文件中存储的对象以流的方式还原成对象
序列化流: ObjectOutputStream
反序列化流: ObjectInputStream
像这样一个接口中如果没有方法,那么这样的接口我们将其称之为标记接口(用来给类打标记的,相当于猪肉身上盖个章)
一个对象可以被序列化的前提是这个对象对应的类必须实现Serializable接口,并显示指定serialVersionUID的值
如果不显示指定serialVersionUID, JVM在序列化时会根据属性自动生成一个serialVersionUID, 然后与属性一起序列化, 再进行持久化或网络传输.
在反序列化时, JVM会再根据属性自动生成一个新版serialVersionUID, 然后将这个新版serialVersionUID与序列化时生成的旧版serialVersionUID进行比较, 如果相同则反序列化成功, 否则报错.如果显示指定了serialVersionUID, JVM在序列化和反序列化时仍然都会生成一个serialVersionUID, 但值为我们显示指定的值, 这样在反序列化时新旧版本的serialVersionUID就一致了.
在实际开发中, 不显示指定serialVersionUID的情况会导致什么问题? 如果我们的类写完后不再修改, 那当然不会有问题, 但这在实际开发中是不可能的, 我们的类会不断迭代, 一旦类被修改了, 那旧对象反序列化就会报错. 所以在实际开发中, 我们都会显示指定一个serialVersionUID, 值是多少无所谓, 只要不变就行.
当我们只在本地JVM里运行下Java实例, 这个时候是不需要什么序列化和反序列化的, 但当我们需要将内存中的对象持久化到磁盘, 数据库中时, 当我们需要与浏览器进行交互进行网络传输时, 这个时候就需要序列化和反序列化了.
Properties
Properties的概述
Properties 类表示了一个持久的属性集。
Properties 可保存在流中或从流中加载。
属性列表中每个键及其对应值都是一个字符串。
Properties父类是Hashtable
属于双列集合,这个集合中的键和值都是字符串 Properties不能指定泛型
方法
- public Object setProperty(String key, String value):用指定的键在属性列表中搜索属性。
- public String getProperty(String key):用指定的键在此属性列表中搜索属性。
- public SetstringPropertyNames():返回此属性列表中的键集,其中该键及其对应值是字符串,如果在主属性列表中未找到同名的键,则还包括默认属性列表中不同的键。
- public void load(Reader reader) :按简单的面向行的格式从输入字符流中读取属性列表(键和元素对)。
- public void load(InputStream inStream): 从输入流中读取属性列表(键和元素对)。
- public void store(OutputStream out,String comments): 以适合使用
load(InputStream) 方法加载到 Properties 表中的格式,将此 Properties
表中的属性列表(键和元素对)写入输出流。 - public void store(Writer writer,String comments) :以适合使用 load(Reader)
方法的格式,将此 Properties 表中的属性列表(键和元素对)写入输出字符。