字节流
输入类FileInputStream 用read()方法接收
输出类OutputStream 用write()方法输出
举个例子
import java.io.*;
public class Ex15_3 {
private String filename; // 文件名
public Ex15_3(String filename) { // 构造方法自定文件名
this.filename = filename;
}
输出字节文件的方法
public void writeToFile(byte[] buffer) throws IOException { // 将缓冲区数据写入指定文件
FileOutputStream fout = new FileOutputStream(this.filename); // 为指定文件创建文件输出流对象
fout.write(buffer); // 将指定字节缓冲区中数据写入输出流
fout.close(); // 关闭输出流
System.out.println("Write to File:" + this.filename);
}
输入字节文件方法
public void readFromFile() throws IOException { // 将指定文件中的数据读到缓冲区
FileInputStream fin = new FileInputStream(this.filename); // 为指定文件创建文件输入流对象
System.out.println("readFromFile:" + this.filename);
byte[] buffer = new byte[512]; // 字节缓冲区
int count = 0;
do {
count = fin.read(buffer); // 读取输入流
System.out.println("count=" + count);
for (int i = 0; i < count; i++)
System.out.print(buffer[i] + " ");
System.out.println();
} while (count != -1); // 输入流未结束时
fin.close();
}
进行文件复制
public void copyFile(String filename2, boolean append) throws IOException { // 将当前文件内容复制到filename2指定文件中,append指定添加或重写方式
FileInputStream fin = new FileInputStream(this.filename);
FileOutputStream fout = new FileOutputStream(filename2, append);
byte[] buffer = new byte[512]; // 字节缓冲区
int count = 0;
do {
count = fin.read(buffer); // 读取输入流
if (count != -1)
fout.write(buffer); // 写入输出流
} while (count != -1);
fin.close();
fout.close();
System.out.println("Copyfile from" + this.filename + " to " + filename2);
}
public void copyFile(String filename2) throws IOException { // 重写方式复制文件,方法重载
copyFile(filename2, false);
}
主方法调用
public static void main(String[] args) throws IOException {
byte[] buffer = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Ex15_3 afile = new Ex15_3("你真棒.txt");
afile.writeToFile(buffer);
afile.readFromFile();
afile.copyFile("你真好.txt");
}
}
结果为
Write to File:你真棒.txt
readFromFile:你真棒.txt
count=10
0 1 2 3 4 5 6 7 8 9
count=-1
Copyfile from你真棒.txt to 你真好.txt
用字节流进行图片复制
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
//复制图片
public class Ex15_3 {
public static void main(String[] args) throws IOException {
File file = new File("C:\\Users\\Mr.MA\\Desktop\\tu.JPG");
FileInputStream fis = new FileInputStream(file); //创建一个输入流
//创建一个输出流,后面一个参数true表示追加,原有内容不会被清除,默认为false
FileOutputStream fos = new FileOutputStream("C:\\Users\\Mr.MA\\Desktop\\tu2.JPG",false);
int ch = 0;
byte[] b = new byte[fis.available()];
fis.read(b); //首先把fis的内容读到字节数组b里面
fos.write(b);//再把字节数组b的内容通过输出流写到指定文件
fos.close();
fis.close();
}
}
这样在我的C:\Users\Mr.MA\Desktop\tu2.JPG这个路径下就成功复制图片
数据字节输入/输出类
数据字节输入/输出类提供直接读或写基本数据类型数据的方法,在读或写某种基本数据类型数据时,不必关心它的实际长度是多少字节。
在类的使用和方法调用可以参考文件IO流,API中对数据流给出了多个read()和write()方法。
需要注意的是套接了节点流
举个例子
public class Ex15_3 {
public static void main(String[] args) throws IOException {
// 注意:套接了节点流FileOutputStream
DataOutputStream out = new DataOutputStream(new FileOutputStream("invoice1.txt"));
double[] prices = { 19.99, 9.99, 15.99, 3.99, 4.99 };
int[] units = { 1,2,3,4,5 };
String[] descs = { "Java T-shirt", "Java Mug", "Duke Juggling Dolls",
"Java Pin", "Java Key Chain" };
for (int i = 0; i < prices.length; i++) {
out.writeDouble(prices[i]);
out.writeChar('\t');
out.writeInt(units[i]);
out.writeChar('\t');
out.writeUTF(descs[i]);
// out.writeChars(descs[i]);
out.writeChar('\n');
}
out.close();
DataInputStream in = new DataInputStream(new FileInputStream("invoice1.txt"));
double price;
int unit;
String desc;
double total = 0.0;
for (int i = 0; i < prices.length; i++) {
price = in.readDouble();
in.readChar(); // 读入tab符
unit = in.readInt();
in.readChar(); // 读入tab符
desc = in.readUTF();
in.readChar(); // 读入换行符
System.out.println("You've ordered " + unit + " units of " + desc
+ " at $" + price);
total = total + unit * price;
}
System.out.println("For a TOTAL of: $" + total);
in.close();
}
}
结果是
You’ve ordered 1 units of Java T-shirt at $19.99
You’ve ordered 2 units of Java Mug at $9.99
You’ve ordered 3 units of Duke Juggling Dolls at $15.99
You’ve ordered 4 units of Java Pin at $3.99
You’ve ordered 5 units of Java Key Chain at $4.99
For a TOTAL of: $128.85000000000002
对象字节流
ObjectOutputStream类能把对象写到一个输出流中,称之为对象序列化,它是一个将对象的状态转换为字节流的过程。
0bjectInputStream类能从一个输入流中读取一个对象,称之为反序列化,它是一个将这些数据再恢复成具有相同状态对象的过程。
在Java语言中,只有实现了Serializable接口的对象才能被序列化和反序列化。
注意:对象流也需要套嵌FileInputStream( );
举个例子
public class Ex15_3 implements Externalizable {
private String name;
private String creditcard;
private int age;
private double salary;
public Ex15_3() {
System.out.println("没有参数的构造器被使用!");
}
public Ex15_3(String name, String creditcard, int age, double salary) {
this.name = name;
this.creditcard = creditcard;
this.age = age;
this.salary = salary;
}
public void writeExternal(ObjectOutput out) throws IOException {
System.out.println("写入对象...");// 本处未对creditcard属性进行序列 化。
out.writeObject(name);
out.writeInt(age);
out.writeDouble(salary);
}
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
System.out.println("读出对象...");
name = (String) in.readObject();
age = in.readInt();
salary = in.readDouble();
}
public String toString() {
return name + " ," + age + " ," + salary;
}
内部类反序列化
static class SerializeTest {
public static void writeO(Ex15_3 p) {
try {
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("test.txt"));
oos.writeObject(p); // 自动调用writeExternal
oos.close();
System.out.println("写入完成!!");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void readO() {
Ex15_3 p = null;
try {
ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("test.txt"));
p = (Ex15_3) ois.readObject();
System.out.println("读出输出");
System.out.println(p);
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Ex15_3 e1 = new Ex15_3("张琦", "110107", 22, 10000);
SerializeTest.writeO(e1);
SerializeTest.readO();
}
}
结果:
写入对象…
写入完成!!
没有参数的构造器被使用!
读出对象…
读出输出
张琦 ,22 ,10000.0
如果实例变量自身指向对象的引用
即序列化的对象中包含另一个对象的引用时的处理,那么处理方式是被引用的类也需要序列化。