01_Io之外的其他流
01.1_数据输入输出流
-
数据输入流:DateInputStream可以写基本数据类
-
数据输出流:DateOutputStream可以读取基本数据类型
特点:能够读写基本数据类型
案例演示:
public static void main(String[] args) {
/*先写后读取
* 分别写出各种基本类型例如:int\double\bollean\UTF
* 怎么写怎么读取
* */
//数据输出流(先写入,后读取)
DataOutputStream dos =null;
try {
dos = new DataOutputStream(new FileOutputStream("Test"));
//写入数据
try {
dos.writeInt(100);
dos.writeBoolean(true);
byte[] bytes = {'a','c'};
dos.writeByte(2);
dos.writeChar('a');
dos.writeDouble(10.66);
dos.writeUTF("笑着哭着都快活");
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//读取数据
DataInputStream dis =null;
try {
dis = new DataInputStream(new FileInputStream("Test"));
try {
System.out.println(dis.readInt());
System.out.println(dis.readBoolean());
System.out.println(dis.readByte());
System.out.println(dis.readChar());
System.out.println(dis.readDouble());
System.out.println(dis.readUTF());
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//关闭流
finally {
try {
if (dos != null) {
dos.close();
}
if (dis != null)
dis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
输出结果
100
true
2
a
10.66
笑着哭着都快活
01.2_内存操作流
- 定义:此流不直接关联任何文件,只在内存中进行读写。
- ByteArrayOutputStream在内存中维护了一个字节数组,作为缓冲区,随着数据的不断写入,缓冲区会自动扩充。
- 可使用toByteArray()和toString()获取缓冲区中的数据。
操作字节数组
案例演示
//字节数组
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
bos.write("有些人".getBytes());
bos.write("我要找到你".getBytes());
//toByteArray(); 取出ByteArrayOutputStream所维护的那个字节数组
byte[] bytes = bos.toByteArray();//[B@4554617c
String s = new String(bytes);
System.out.println(s);//有些人我要找到你
//或者直接用toString打印
System.out.println(bos.toString());
} catch (IOException e) {
e.printStackTrace();
}
操作字符数组
案例演示
//字符数组
CharArrayWriter caw = new CharArrayWriter();
try {
caw.write("我要到可可西里看一看海");
//字符数组
caw.write(new char[]{'a','b','c'});
System.out.println(caw.toCharArray());//我要到可可西里看一看海abc
} catch (IOException e) {
e.printStackTrace();
}
操作字符串
案例演示
//字符串
StringWriter sw = new StringWriter();
sw.write("走走停停");
sw.write("\r\n");
sw.write("我逛了几个世纪");
System.out.println(sw.toString());
01.3_打印流:只能写出数据不能读取数据,单个的,不是成对的
- 字节打印流:PrintStream
- 字符打印流:PrintWriter
案列演示:分为字节打印流PrintStream(File file),字符打印流PrintStream(OutputStream out, boolean autoFlush)
打印流复制文件
//打印流复制文件
/* FileInputStream fis = null;
try {
fis = new FileInputStream("F:\\桌面\\我的简历.docx");
PrintWriter pw = new PrintWriter("C:\\Users\\Liu's mood\\Desktop\\Test.docx");
int len = 0;
byte[] bytes = new byte[1024 * 8];
while ((fis.read(bytes)) != -1) {
pw.print(bytes);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//关流
finally {
try {
if (fis != null) {
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}*/
PrintWriter pw = new PrintWriter("C:\\Users\\Liu's mood\\Desktop\\Test.docx");
BufferedReader br = new BufferedReader(new FileReader("F:\\\\桌面\\\\我的简历.docx"));
while (true) {
String s = br.readLine();
if (s != null) {
pw.print(s);
}
01.4_随机访问流
- 定义:RandomAcessFile,能读能写。
- 不属于流,是Object类的子类。但它融合了InputStream和OutputStream的功能。
- 定位文件指针位置 :seek();
writeData();
RandomAccessFile in = new RandomAccessFile("e.txt", "rw");
int i = in.readInt();
long filePointer = in.getFilePointer();
System.out.println("指针位置:"+filePointer);
01.5_序列化流
序列化流:ObjectOutputStream就是把对象通过流的方式存储到文件中
bjectInputStream in = new ObjectInputStream(new FileInputStream("student.txt"));
Student s = (Student) in.readObject();
System.out.println(s.getName()+"=="+s.getAge());
反序列化流:ObjectInputStream 就是把文件中存储的对象以流的方式还原成对象
Student s1 = new Student("张三", 23);
//NotSerializableException
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("student.txt"));
out.writeObject(s1);
- 使用transient关键字声明不需要序列化的成员变量
- 我们的一个类可以被序列化的前提是需要这个类实现Serializable接口,就需要给这个类添加一个标记.
解决序列化时候的黄色警告线问题
- 在完成序列化以后,序列化文件中还存在一个标记,然后在进行反序列化的时候,
会验证这个标记和序列化前的标记是否一致,如果一致就正常进行反序列化,如果 - 不一致就报错了. 而现在我们把这个类做了修改,将相当于更改了标记,而导致这两个标记不一致,就报错了.
- 解决问题: 只要让这个两个标记一致,就不会报错了吧
- 怎么让这两个标记一致呢? 不用担心,很简单,难道你们没有看见黄色警告线吗? alt+enter, 生成出来
- private static final long serialVersionUID = -7602640005373026150L;
01.6_Properties
Properties` 类表示了一个持久的属性集。`Properties
可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。
Properties父类是Hashtable, 属于双列集合,这个集合中的键和值都是字符串 Properties不能指定泛型
Properties的特殊功能
public Object setProperty(String key,String value)
public String getProperty(String key)
public Set<String> stringPropertyNames()
结合Io流的使用功能
Properties的load()和store()功能
Properties和IO流进行配合使用:
public void load(Reader reader): 读取键值对数据把数据存储到Properties中
- public void store(Writer writer, String comments)把Properties集合中的键值对数据写入到文件中, comments注释
作用于读取配置文件中的数据
Properties properties = new Properties();
properties.setProperty("username", "zhangsan");//添加数据:相当于Hashtable 的方法 put
String username = properties.getProperty("username2");//用指定的键在此属性列表中搜索值。
properties.store(new FileOutputStream("MyUser.properties"),null);//把Properties集合中的键值对数据写入到文件中, comments注释
01.7_SequenceInputStream
定义:表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。
构造方法
SequenceInputStream(InputStream s1, InputStream s2)
通过记住这两个参数来初始化新创建的 SequenceInputStream(将按顺序读取这两个参数,先读取 s1,然后读取 s2),以提供从此 SequenceInputStream 读取的字节。
SequenceInputStream(Enumeration<? extends InputStream> e)
通过记住参数来初始化新创建的 SequenceInputStream,该参数必须是生成运行时类型为 InputStream 对象的 Enumeration 型参数。
案例演示:将a.txt和b.txt两个文本文件的内容合并到c.txt
FileInputStream in1 = new FileInputStream("a.txt");
FileInputStream in2 = new FileInputStream("b.txt");
//连续读取两个文件
SequenceInputStream allIn = new SequenceInputStream(in1, in2);
//合并到指定文件
FileOutputStream out = new FileOutputStream("ff.txt");
//复制操作
int len=0;
byte[] bytes = new byte[1024];
while ((len=allIn.read(bytes))!=-1){
out.write(bytes,0,len);
out.flush();
}
allIn.close();
out.close();
SequenceInputStream(Enumeration < ? extends InputStream > e)
Enumeration:实现 Enumeration 接口的对象,它生成一系列元素,一次生成一个。连续调用 nextElement
方法将返回一系列的连续元素。
FileInputStream in1 = new FileInputStream("a.txt");
FileInputStream in2 = new FileInputStream("b.txt");
FileInputStream in3 = new FileInputStream("b.txt");
Vector<FileInputStream> vector = new Vector<>();
vector.add(in1);
vector.add(in2);
vector.add(in3);
/* SequenceInputStream(Enumeration < ? extends InputStream > e)
通过记住参数来初始化新创建的 SequenceInputStream,该参数必须是生成运行时类型为 InputStream 对象的 Enumeration 型参数。*/
// Enumeration集合中的元素
Enumeration<FileInputStream> elements = vector.elements();
//读取数据
SequenceInputStream allIn = new SequenceInputStream(elements);
//写入新的文件中
FileOutputStream out = new FileOutputStream("ff.txt");
//复制操作
int len = 0;
byte[] bytes = new byte[1024];
while ((len = allIn.read(bytes)) != -1) {
out.write(bytes, 0, len);
out.flush();
}
allIn.close();
out.close();
}