IO流(其他流)
一、数据输入输出流
1、特有属性
特点:可以读写基本类型数据
数据输入流:
DataInputStream(InputStream in)
数据输出流:
DataOutputStream(OutputStream out)
2、特有方法演示
import java.io.*;
public class MyTest {
public static void main(String[] args) throws IOException {
write();
read();
}
private static void read() throws IOException {
DataInputStream in = new DataInputStream(new FileInputStream("a.txt"));
boolean b = in.readBoolean();
byte b1 = in.readByte();
char c = in.readChar();
String s = in.readUTF();
in.close();
}
private static void write() throws IOException {
DataOutputStream out = new DataOutputStream(new FileOutputStream("a.txt"));
out.writeBoolean(true);
out.writeByte(99);
out.writeChar('1');
out.writeUTF("abc");
out.close();
}
}
二、内存操作流
不关联任何文件,只是在内存中对数据进行操作,此流无需关闭,关闭无效
1、操作字节数组的内存操作流
ByteArrayOutputStream:此类实现了一个输出流,其中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray() 和 toString() 获取数据。
ByteArrayInputStream :包含一个内部缓冲区,该缓冲区包含从流中读取的字节
演示:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;
public class MyTest1 {
public static void main(String[] args) throws IOException {
ByteArrayOutputStream baOut = new ByteArrayOutputStream();
baOut.write("abcd".getBytes());
baOut.write("1234".getBytes());
byte[] bytes = baOut.toByteArray();
System.out.println(Arrays.toString(bytes));
String s = baOut.toString();
System.out.println(s);
ByteArrayInputStream baIn = new ByteArrayInputStream(bytes);
byte[] bytes1 = new byte[1024 * 8];
int len = baIn.read(bytes1);
String s1 = new String(bytes1, 0, len);
System.out.println(s1);
}
}
2、操作字符数组的内存操作流
import java.io.CharArrayWriter;
import java.io.IOException;
public class MyTest2 {
public static void main(String[] args)throws IOException {
CharArrayWriter writer = new CharArrayWriter();
writer.write("abc");
writer.write("abc");
char[] chars = writer.toCharArray();
String s = writer.toString();
}
}
3、操作字符串的内存操作流程
import java.io.StringWriter;
public class MyTest3 {
public static void main(String[] args) {
StringWriter stringWriter = new StringWriter();
stringWriter.write("abc");
stringWriter.append("abc");
String s = stringWriter.toString();
System.out.println(s);
}
}
三、打印流
打印流的特点
a: 打印流只能操作目的地,不能操作数据源(不能读取数据)
b: 可以操作任意数据类型的数据 调用print() 方法可以写任意数据类型
c: 自动刷新:必须调用println、printf 或 format 方法中的一个方法,且通过以下构造创建对象,能够启动自动刷新
public PrintWriter(OutputStream out, boolean autoFlush)
public PrintWriter(Writer out, boolean autoFlush)
d: 这个流可以直接对文件进行操作(构造方法的参数可以传递文件或者文件路径)
1、字符打印流
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
public class MyTest4 {
public static void main(String[] args) throws IOException {
PrintWriter writer = new PrintWriter(new FileOutputStream("c.txt"),true);
writer.println("abc");
writer.println(123);
writer.println(true);
writer.close();
}
}
2、字节打印流
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
public class MyTest5 {
public static void main(String[] args) throws IOException {
PrintStream printStream = new PrintStream(new FileOutputStream("b.txt"));
printStream.write("字节打印流".getBytes());
printStream.print(true);
printStream.println(100);
printStream.close();
PrintStream out = System.out;
out.write("abc".getBytes());
out.println(3.14);
}
}
3、使用字节打印流和Scanner类复制文本文件
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;
public class MyTest7 {
public static void main(String[] args)throws IOException {
Scanner sc = new Scanner(new FileInputStream("a.txt"));
PrintWriter writer = new PrintWriter("b.txt");
while (sc.hasNextLine()){
writer.println(sc.nextLine());
writer.flush();
}
sc.close();
writer.close();
}
}
四、序列化与反序列化流
序列化:把对象保存到硬盘上
反序列化:把对象读到内存中
序列化流:
ObjectOutputStream
out.writeObject(对象);
public static final long serialVersionUID=1L;
反序列化流:
ObjeceInputStream
in.readObject();
演示
import java.io.*;
import java.util.ArrayList;
public class MyTest4 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
write();
ObjectInputStream objIn = new ObjectInputStream(new FileInputStream("a.txt"));
Object object = objIn.readObject();
ArrayList<Student> list= (ArrayList<Student>) object;
for (Student student : list) {
System.out.println(student.getName());
}
}
private static void write() throws IOException {
Student zhangsan = new Student("zhangsan");
Student lisi = new Student("lisi");
Student wangwu = new Student("wangwu");
ArrayList<Student> list = new ArrayList<>();
list.add(zhangsan);
list.add(lisi);
list.add(wangwu);
ObjectOutputStream objout = new ObjectOutputStream(new FileOutputStream("a.txt"));
objout.writeObject(list);
}
}
class Student implements Serializable{
public static final long serialVersionUID = -3508803735981209248L;
private String name;
public Student() {
}
public Student(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
五、随机访问流
RandomAccessFile特点:能读能写,有文件指针,可以记录文件读写的位置
RandomAccessFile(fileName,"rw“)
获取文件指针位置:getFilePointer()
设置指针位置:seek()
1、演示
import java.io.IOException;
import java.io.RandomAccessFile;
public class MyTest4 {
public static void main(String[] args)throws IOException {
RandomAccessFile ra = new RandomAccessFile("e.txt", "rw");
RandomAccessFile ra2 = new RandomAccessFile("e.txt", "rw");
ra.writeBoolean(true);
boolean b = ra2.readBoolean();
System.out.println(b);
long l = ra2.getFilePointer();
System.out.println(l);
ra2.seek(0);
boolean b1 = ra2.readBoolean();
System.out.println(b1);
}
}
2、例题:将一个文件复制三遍
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
public class CopyFile {
public static void main(String[] args) throws IOException {
File file = new File("许巍 - 曾经的你.mp3");
RandomAccessFile ra = new RandomAccessFile(file, "rw");
for (int i = 1; i <= 3; i++) {
File f = new File(i+".许巍 - 曾经的你.mp3");
RandomAccessFile ra1 = new RandomAccessFile(f, "rw");
int len=0;
byte[] bytes = new byte[1024 * 1024];
while ((len=ra.read(bytes))!=-1){
ra1.write(bytes,0,len);
}
ra1.close();
ra.seek(0);
}
ra.close();
}
}
六、Properties
属性:集合,经常用来读写配置文件,属于双列集合,规定键只能是String类型
用此集合特有方法来存储键值对:
pro.setProperty(key,value);
获取键值:
pro.getProperty(key);
pro.getProperty(key,value);
读取配置文件:
pro.load(new FileReader(file));
要求配置文件键值用“=”连接
写配置文件:
pro.store(new FileWriter("文件名"),null);
演示
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
public class MyTest5 {
public static void main(String[] args) throws IOException {
Properties properties = new Properties();
properties.setProperty("a","aaa");
String a = properties.getProperty("a");
System.out.println(a);
String s1 = properties.getProperty("b", "bbb");
System.out.println(s1);
properties.setProperty("b","bbb");
properties.store(new FileWriter("ab.properties"),null);
properties.load(new FileReader("ab.properties"));
System.out.println(properties);
}
}
配置文件内容:
#Thu Jul 25 15:17:20 CST 2019
b=bbb
a=aaa
七、SequenceInputStream
SequenceInputStream
表示其他输入流的逻辑串联。
它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止
构造方法:
SequenceInputStream(InputStream s1, InputStream s2)
通过记住这两个参数来初始化新创建的 SequenceInputStream(将按顺序读取这两个参数,先读取 s1,然后读取 s2),以提供从此 SequenceInputStream 读取的字节。
SequenceInputStream(Enumeration<? extends InputStream> e)
通过记住参数来初始化新创建的 SequenceInputStream,该参数必须是生成运行时类型为 InputStream 对象的 Enumeration 型参数(迭代器)。
演示
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.Enumeration;
import java.util.Vector;
public class MergeFile {
public static void main(String[] args)throws IOException {
Vector<FileInputStream> vector = new Vector<>();
for (int i = 1; i <= 5; i++) {
FileInputStream in = new FileInputStream(i + ".许巍 - 蓝莲花.mp3");
vector.add(in);
}
Enumeration<FileInputStream> elements = vector.elements();
SequenceInputStream sIn = new SequenceInputStream(elements);
FileOutputStream out = new FileOutputStream("1许巍 - 蓝莲花.mp3");
int len;
byte[] bytes = new byte[1024 * 1024];
while ((len=sIn.read(bytes))!=-1){
out.write(bytes,0,len);
out.flush();
}
sIn.close();
out.close();
}
}