Java中的字节流

字节流

输入类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

如果实例变量自身指向对象的引用
即序列化的对象中包含另一个对象的引用时的处理,那么处理方式是被引用的类也需要序列化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值