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();
}
}