JAVA-IO学习(笔记)

JAVA-IO
一.InputStream
1. 类图
附件
2. 子类说明
流的数据方法都用了native实现方式,都不知道哪里去看实现。
2.1  ByteArrayInputStream
     把字节数组数据转化为输入流;通过byte数组实现数据的存取
     重要变量:
Java代码
protected byte buf[];    //缓冲区数据  
protected int pos;      //下一个读取字符的位置  
protected int mark = 0;  //当前位置标记  
protected int count;     //需要读入(或现有)数据长度 

protected byte buf[];    //缓冲区数据
protected int pos;      //下一个读取字符的位置
protected int mark = 0;  //当前位置标记
protected int count;     //需要读入(或现有)数据长度

2.2  FileInputStream
从文件中读取数据,他的子类中有socketInputStream
重要变量:
Java代码
private FileDescriptor fd;   //文件描述,文件类型读取方式的记录   
FileChannel channel = null;  //文件的链接 

            private FileDescriptor fd;   //文件描述,文件类型读取方式的记录
     private FileChannel channel = null;  //文件的链接

2.3  PipedInputStream
    管道输入流应该连接到管道输出流;管道输入流提供要写入管道输出流的所有数据字节。通常,数据由某个线程从 PipedInputStream 对象读取,并由其他线程将其写入到相应的 PipedOutputStream。不建议对这两个对象尝试使用单个线程,因为这样可能死锁线程。管道输入流包含一个缓冲区,可在缓冲区限定的范围内将读操作和写操作分离开。如果向连接管道输出流提供数据字节的线程不再存在,则认为该管道已损坏

重要变量:
Java代码
boolean closedByWriter = false;  
             volatile boolean closedByReader = false;  
             boolean connected = false;  
             Thread readSide;     //当前读线程  
             Thread writeSide;    //当前写线程  
             protected byte buffer[] = new byte[PIPE_SIZE]; //缓冲区数据 初始PIPE_SIZE=1024 

boolean closedByWriter = false;
             volatile boolean closedByReader = false;
             boolean connected = false;
             Thread readSide;     //当前读线程
    Thread writeSide;    //当前写线程
     protected byte buffer[] = new byte[PIPE_SIZE]; //缓冲区数据 初始PIPE_SIZE=1024             通过标记closedByWriter  closedByReader  可以对当前数据进行锁处理,

             例子:
Java代码
--------------------------写数据--------------------------------  
public class RunPipedMain {  
 
    public static void main(String... strings) {  
        ReceiverThread read = new ReceiverThread();  
        WriterThread write = new WriterThread();  
        PipedInputStream in = read.getIn();  
        PipedOutputStream out = write.getOut();  
        try {  
            out.connect(in);  
        } catch (IOException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
 
        write.start();  
 
        read.start();  
    }  
}  
--------------------------接受--------------------------------  
public class ReceiverThread extends Thread {  
 
    private PipedInputStream in;  
 
    public PipedInputStream getIn() {  
        if (in == null) in = new PipedInputStream();  
        return in;  
    }  
 
    public void run() {  
        System.out.println("read..............");  
        byte[] buf = new byte[1024]; // 字节数组  
        try { // read和close方法都可能有异常出现  
            int len = in.read(buf); // 读取数据,len表示实际读取到的内容(长度)  
            System.out.println("the following message comes from sender:\n" + new String(buf, 0, len));  
            in.close();  
        } catch (IOException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
    }  
}  
 
--------------------------运行---------------------------------  
public class RunPipedMain {  
 
    public static void main(String... strings) {  
        ReceiverThread read = new ReceiverThread();  
        WriterThread write = new WriterThread();  
        PipedInputStream in = read.getIn();  
        PipedOutputStream out = write.getOut();  
        try {  
            out.connect(in);  
        } catch (IOException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
 
        write.start();  
 
        read.start();  
    }  
}  
--------------------------运行结果--------------------------------  
1.  write..............  
2.  read..............  
3.  the following message comes from sender:  
4.  test out........... 

--------------------------写数据--------------------------------
public class RunPipedMain {

    public static void main(String... strings) {
        ReceiverThread read = new ReceiverThread();
        WriterThread write = new WriterThread();
        PipedInputStream in = read.getIn();
        PipedOutputStream out = write.getOut();
        try {
            out.connect(in);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        write.start();

        read.start();
    }
}
--------------------------接受--------------------------------
public class ReceiverThread extends Thread {

    private PipedInputStream in;

    public PipedInputStream getIn() {
        if (in == null) in = new PipedInputStream();
        return in;
    }

    public void run() {
        System.out.println("read..............");
        byte[] buf = new byte[1024]; // 字节数组
        try { // read和close方法都可能有异常出现
            int len = in.read(buf); // 读取数据,len表示实际读取到的内容(长度)
            System.out.println("the following message comes from sender:\n" + new String(buf, 0, len));
            in.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

--------------------------运行---------------------------------
public class RunPipedMain {

    public static void main(String... strings) {
        ReceiverThread read = new ReceiverThread();
        WriterThread write = new WriterThread();
        PipedInputStream in = read.getIn();
        PipedOutputStream out = write.getOut();
        try {
            out.connect(in);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        write.start();

        read.start();
    }
}
--------------------------运行结果--------------------------------
1.  write..............
2.  read..............
3.  the following message comes from sender:
4.  test out...........问1:看着结果,我想到一点,为什么不论是哪个线程先运行,都会先写后读呢?
即运行结果中1, 2两步的运行顺序是不可确定的。  难道pipedInputStream会去等待么?

查看代码中: pipedInputStream中read()方法,通过判断connected变来,知道当前是否连接,如果链接则判断closedByWriter变量,看是否已经被out给关闭,然后如果没有关闭的话,判断in变量是否小于0(小于0代表数据还没读到),小于0就wait(1000),大于零就开始取数据:
代码如下:
   Java代码
public synchronized int read()  throws IOException {  
        if (!connected) {  
            throw new IOException("Pipe not connected");  
        } else if (closedByReader) {  
        throw new IOException("Pipe closed");  
    } else if (writeSide != null && !writeSide.isAlive()  
                   && !closedByWriter && (in < 0)) {  
            throw new IOException("Write end dead");  
        }  
 
        readSide = Thread.currentThread();  
    int trials = 2;  
    while (in < 0) {  
        if (closedByWriter) {  
        /* closed by writer, return EOF */ 
        return -1;  
        }  
        if ((writeSide != null) && (!writeSide.isAlive()) && (--trials < 0)) {  
        throw new IOException("Pipe broken");  
        }  
            /* might be a writer waiting */ 
        notifyAll();  
        try {  
            wait(1000);  
        } catch (InterruptedException ex) {  
        throw new java.io.InterruptedIOException();  
        }  
    }  
    int ret = buffer[out++] & 0xFF;  
    if (out >= buffer.length) {  
        out = 0;  
    }  
    if (in == out) {  
            /* now empty */ 
        in = -1;  
    }  
    return ret;  


public synchronized int read()  throws IOException {
        if (!connected) {
            throw new IOException("Pipe not connected");
        } else if (closedByReader) {
    throw new IOException("Pipe closed");
} else if (writeSide != null && !writeSide.isAlive()
                   && !closedByWriter && (in < 0)) {
            throw new IOException("Write end dead");
        }

        readSide = Thread.currentThread();
int trials = 2;
while (in < 0) {
    if (closedByWriter) {
/* closed by writer, return EOF */
return -1;
    }
    if ((writeSide != null) && (!writeSide.isAlive()) && (--trials < 0)) {
throw new IOException("Pipe broken");
    }
            /* might be a writer waiting */
    notifyAll();
    try {
        wait(1000);
    } catch (InterruptedException ex) {
throw new java.io.InterruptedIOException();
    }
}
int ret = buffer[out++] & 0xFF;
if (out >= buffer.length) {
    out = 0;
}
if (in == out) {
            /* now empty */
    in = -1;
}
return ret;
}
问2:  in和 out变量是什么时候修改的?


2.4  SequenceInputStream
SequenceInputStream 表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。

重要变量:
                Java代码
Enumeration e;  //存取InputStream的枚举类  
  InputStream in;  //枚举类中,当前的InputStream对象 

  Enumeration e;  //存取InputStream的枚举类
    InputStream in;  //枚举类中,当前的InputStream对象
    他是通过传入Enumeration,在之间取到Enumeration,进行IO操作。

例子:
Java代码
public class EnumerationInputStreamTest {  
 
    Enumeration         e    = null;       // 由内部类实现,如Vector  
    String              sss  = "testsetst";  
    SequenceInputStream seq  = null;  
    Vector              coll = null;  
 
    public void test() {  
        try {  
            FileInputStream file = new FileInputStream("c:\\boot.ini");  
            ByteArrayInputStream byteArray = new ByteArrayInputStream(sss.getBytes());  
            coll = new Vector();  
            coll.add(byteArray);  
            coll.add(file);  
            e = ((Vector) coll).elements();  
            seq = new SequenceInputStream(e);  
            int i = 0;  
            while (i != -1) {  
                i = seq.read();  
                System.out.println("out:" + i);  
            }  
        } catch (FileNotFoundException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (IOException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
    }  
 
    public static void main(String... strings) {  
        EnumerationInputStreamTest eee = new EnumerationInputStreamTest();  
        eee.test();  
    }  
}  
 
运行结果:   
out:116 
out:101 
out:115 
…  
out:13 
out:-1  

public class EnumerationInputStreamTest {

    Enumeration         e    = null;       // 由内部类实现,如Vector
    String              sss  = "testsetst";
    SequenceInputStream seq  = null;
    Vector              coll = null;

    public void test() {
        try {
            FileInputStream file = new FileInputStream("c:\\boot.ini");
            ByteArrayInputStream byteArray = new ByteArrayInputStream(sss.getBytes());
            coll = new Vector();
            coll.add(byteArray);
            coll.add(file);
            e = ((Vector) coll).elements();
            seq = new SequenceInputStream(e);
            int i = 0;
            while (i != -1) {
                i = seq.read();
                System.out.println("out:" + i);
            }
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public static void main(String... strings) {
        EnumerationInputStreamTest eee = new EnumerationInputStreamTest();
        eee.test();
    }
}

运行结果:
out:116
out:101
out:115

out:13
out:-1

2.5  ObjectInputStream
   这里转一下网上的文章,感觉写的不错。
源文件地址:
http://hi.baidu.com/mdbing/blog/item/4612cb13decfc4075aaf53fa.html
      Java程序执行的过程中,很多数据都是以对 象的方式存在于内存中。有时会希望直接将内存中整个对象存储至文件,而不是只存储对象中的某些基本类型成员信息,而在下一次程序运行时,希望可以从文件中 读出数据并还原为对象。这时可以使用java.io.ObjectInputStream和java.io.ObjectOutputStream来进行 这项工作
      如果要直接存储对象,定义该对象的类必须实现java.io.Serializable接口,不过Serializable接口中并没有规范任何必须实现的方法,所以这里所谓实现的意义,其实像是对对象贴上一个标志,代表该对象是可序列化的(Serializable)。
      为了说明如何直接存储对象,先来实现一个User类
Java代码
Java代码
import java.io.Serializable;     
    
public class User implements Serializable {      
    private static final long serialVersionUID = 1L;      
    private String name;      
    private int number;      
    public User() {      
    }      
    public User(String name, int number) {     
        this.name = name;     
        this.number = number;     
    }      
    public String getName() {     
        return name;     
    }      
    public void setName(String name) {     
        this.name = name;     
    }      
    public int getNumber() {     
        return number;     
    }      
    public void setNumber(int number) {     
        this.number = number;     
    }      
}    
import java.io.Serializable;   
public class User implements Serializable {   
    private static final long serialVersionUID = 1L;   
    private String name;   
    private int number;   
    public User() {   
    }   
 
    public User(String name, int number) {  
        this.name = name;  
        this.number = number;  
    }  
 
    public String getName() {  
        return name;  
    }  
 
    public void setName(String name) {  
        this.name = name;  
    }  
 
    public int getNumber() {  
        return number;  
    }  
 
    public void setNumber(int number) {  
        this.number = number;  
    }  
 


import java.io.Serializable;  
 
public class User implements Serializable {   
    private static final long serialVersionUID = 1L;   
    private String name;   
    private int number;   
    public User() {   
    }   
    public User(String name, int number) {  
        this.name = name;  
        this.number = number;  
    }   
    public String getName() {  
        return name;  
    }   
    public void setName(String name) {  
        this.name = name;  
    }   
    public int getNumber() {  
        return number;  
    }   
    public void setNumber(int number) {  
        this.number = number;  
    }   

import java.io.Serializable;
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private int number;
public User() {
}

public User(String name, int number) {
this.name = name;
this.number = number;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getNumber() {
return number;
}

public void setNumber(int number) {
this.number = number;
}

}
注意到serialVersionUID,它代 表了可序列化对象的版本。如果没有提供这个版本信息,则实现Serializable接口的类会自动依类名称、实现的接口、成员等来产生。如果是自动产生 的,则下次更改User类,自动产生的serialVersionUID也会跟着变更,从文件读回对象时若两个对象的serialVersionUID不 相同,就会丢出java.io.InvalidClassException。如果想要维持版本信息的一致,则要明确声明 serialVersionUID。
ObjectInputStream和 ObjectOutputStream为InputStream、OutputStream的实例加上了可以让用户写入对象与读出对象的功能。在写入对象 时,要使用writeObject()方法,读出对象时则使用readObject()方法,被读出的对象都是以Object的类型返回。所以必须将之转 换为对象原来的类型,才能正确地实现被读回的对象。示范了如何存储User对象至文件中,然后再将它读回并还原为User实例
Java代码
Java代码
import java.io.File;     
import java.io.FileInputStream;     
import java.io.FileNotFoundException;     
import java.io.FileOutputStream;     
import java.io.IOException;     
import java.io.ObjectInputStream;     
import java.io.ObjectOutputStream;     
import java.util.ArrayList;     
import java.util.List;     
    
public class ObjectStreamDemo {     
    
    public static void main(String args[]) {     
        User[] users = { new User("cater", 101), new User("justin", 102) };     
        // 写入新文件     
        writeObjectsToFile(users, args[0]);     
        try {     
            // 读取文件数据     
            users = readObjectsFromFile(args[0]);     
            // 显示读回的对象     
            for (User user : users) {     
                System.out.printf("%s\t%d%n", user.getName(), user.getNumber());     
            }     
            System.out.println();     
    
            users = new User[2];     
            users[0] = new User("momor", 103);     
            users[1] = new User("becky", 104);     
    
            // 附加新对象至文件     
            appendObjectsToFile(users, args[0]);     
    
            // 读取文件数据     
            users = readObjectsFromFile(args[0]);     
            // 显示读回的对象     
            for (User user : users) {     
                System.out.printf("%s\t%d\n", user.getName(), user.getNumber());     
            }     
    
        } catch (ArrayIndexOutOfBoundsException e) {     
            e.printStackTrace();     
        } catch (FileNotFoundException e) {     
            e.printStackTrace();     
        }     
    }     
    
    public static void writeObjectsToFile(Object[] objs, String filename) {     
        File file = new File(filename);     
        try {     
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(     
                    new FileOutputStream(file));     
            for (Object obj : objs) {     
                // 将对象写入文件     
                objectOutputStream.writeObject(obj);     
            }     
            objectOutputStream.close();     
        } catch (FileNotFoundException e) {     
            e.printStackTrace();     
        } catch (IOException e) {     
            // TODO Auto-generated catch block     
            e.printStackTrace();     
        }     
    }     
    
    public static User[] readObjectsFromFile(String fileName)     
            throws FileNotFoundException {     
        File file = new File(fileName);     
        // 如果文件不存在就丢出异常     
        if (!file.exists())     
            throw new FileNotFoundException("未找到文件" + fileName);     
        // 使用List先读取出对象     
        List<User> list = new ArrayList();     
        try {     
            FileInputStream fileInputStream = new FileInputStream(file);     
            ObjectInputStream objectInputStream = new ObjectInputStream(     
                    fileInputStream);     
            while (fileInputStream.available() > 0) {     
                list.add((User) objectInputStream.readObject());     
            }     
            objectInputStream.close();     
    
        } catch (IOException e) {     
            e.printStackTrace();     
        } catch (ClassNotFoundException e) {     
            // TODO Auto-generated catch block     
            e.printStackTrace();     
        }     
        User[] users = new User[list.size()];     
        return list.toArray(users);     
    }     
    
    public static void appendObjectsToFile(Object[] objs, String fileName)     
            throws FileNotFoundException {     
        File file = new File(fileName);     
        if (!file.exists())     
            throw new FileNotFoundException("未发现文件" + fileName);     
        try {     
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(     
                    new FileOutputStream(fileName, true)) {     
                // 如果要附加对象到文件后     
                // 必须重新定义这个方法     
                protected void writeStreamHeader() throws IOException {     
                }     
            };     
            for (Object obj : objs) {     
                objectOutputStream.writeObject(obj);     
            }     
            objectOutputStream.close();     
    
        } catch (IOException e) {     
            e.printStackTrace();     
        }     
    
    }     
}    
import java.io.File;  
import java.io.FileInputStream;  
import java.io.FileNotFoundException;  
import java.io.FileOutputStream;  
import java.io.IOException;  
import java.io.ObjectInputStream;  
import java.io.ObjectOutputStream;  
import java.util.ArrayList;  
import java.util.List;  
 
public class ObjectStreamDemo {  
 
    public static void main(String args[]) {  
        User[] users = { new User("cater", 101), new User("justin", 102) };  
        // 写入新文件  
        writeObjectsToFile(users, args[0]);  
        try {  
            // 读取文件数据  
            users = readObjectsFromFile(args[0]);  
            // 显示读回的对象  
            for (User user : users) {  
                System.out.printf("%s\t%d%n", user.getName(), user.getNumber());  
            }  
            System.out.println();  
 
            users = new User[2];  
            users[0] = new User("momor", 103);  
            users[1] = new User("becky", 104);  
 
            // 附加新对象至文件  
            appendObjectsToFile(users, args[0]);  
 
            // 读取文件数据  
            users = readObjectsFromFile(args[0]);  
            // 显示读回的对象  
            for (User user : users) {  
                System.out.printf("%s\t%d\n", user.getName(), user.getNumber());  
            }  
 
        } catch (ArrayIndexOutOfBoundsException e) {  
            e.printStackTrace();  
        } catch (FileNotFoundException e) {  
            e.printStackTrace();  
        }  
    }  
 
    public static void writeObjectsToFile(Object[] objs, String filename) {  
        File file = new File(filename);  
        try {  
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(  
                    new FileOutputStream(file));  
            for (Object obj : objs) {  
                // 将对象写入文件  
                objectOutputStream.writeObject(obj);  
            }  
            objectOutputStream.close();  
        } catch (FileNotFoundException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
    }  
 
    public static User[] readObjectsFromFile(String fileName)  
            throws FileNotFoundException {  
        File file = new File(fileName);  
        // 如果文件不存在就丢出异常  
        if (!file.exists())  
            throw new FileNotFoundException("未找到文件" + fileName);  
        // 使用List先读取出对象  
        List<User> list = new ArrayList();  
        try {  
            FileInputStream fileInputStream = new FileInputStream(file);  
            ObjectInputStream objectInputStream = new ObjectInputStream(  
                    fileInputStream);  
            while (fileInputStream.available() > 0) {  
                list.add((User) objectInputStream.readObject());  
            }  
            objectInputStream.close();  
 
        } catch (IOException e) {  
            e.printStackTrace();  
        } catch (ClassNotFoundException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
        User[] users = new User[list.size()];  
        return list.toArray(users);  
    }  
 
    public static void appendObjectsToFile(Object[] objs, String fileName)  
            throws FileNotFoundException {  
        File file = new File(fileName);  
        if (!file.exists())  
            throw new FileNotFoundException("未发现文件" + fileName);  
        try {  
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(  
                    new FileOutputStream(fileName, true)) {  
                // 如果要附加对象到文件后  
                // 必须重新定义这个方法  
                protected void writeStreamHeader() throws IOException {  
                }  
            };  
            for (Object obj : objs) {  
                objectOutputStream.writeObject(obj);  
            }  
            objectOutputStream.close();  
 
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
 
    }  
}  

import java.io.File;  
import java.io.FileInputStream;  
import java.io.FileNotFoundException;  
import java.io.FileOutputStream;  
import java.io.IOException;  
import java.io.ObjectInputStream;  
import java.io.ObjectOutputStream;  
import java.util.ArrayList;  
import java.util.List;  
 
public class ObjectStreamDemo {  
 
    public static void main(String args[]) {  
        User[] users = { new User("cater", 101), new User("justin", 102) };  
        // 写入新文件  
        writeObjectsToFile(users, args[0]);  
        try {  
            // 读取文件数据  
            users = readObjectsFromFile(args[0]);  
            // 显示读回的对象  
            for (User user : users) {  
                System.out.printf("%s\t%d%n", user.getName(), user.getNumber());  
            }  
            System.out.println();  
 
            users = new User[2];  
            users[0] = new User("momor", 103);  
            users[1] = new User("becky", 104);  
 
            // 附加新对象至文件  
            appendObjectsToFile(users, args[0]);  
 
            // 读取文件数据  
            users = readObjectsFromFile(args[0]);  
            // 显示读回的对象  
            for (User user : users) {  
                System.out.printf("%s\t%d\n", user.getName(), user.getNumber());  
            }  
 
        } catch (ArrayIndexOutOfBoundsException e) {  
            e.printStackTrace();  
        } catch (FileNotFoundException e) {  
            e.printStackTrace();  
        }  
    }  
 
    public static void writeObjectsToFile(Object[] objs, String filename) {  
        File file = new File(filename);  
        try {  
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(  
                    new FileOutputStream(file));  
            for (Object obj : objs) {  
                // 将对象写入文件  
                objectOutputStream.writeObject(obj);  
            }  
            objectOutputStream.close();  
        } catch (FileNotFoundException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
    }  
 
    public static User[] readObjectsFromFile(String fileName)  
            throws FileNotFoundException {  
        File file = new File(fileName);  
        // 如果文件不存在就丢出异常  
        if (!file.exists())  
            throw new FileNotFoundException("未找到文件" + fileName);  
        // 使用List先读取出对象  
        List<User> list = new ArrayList();  
        try {  
            FileInputStream fileInputStream = new FileInputStream(file);  
            ObjectInputStream objectInputStream = new ObjectInputStream(  
                    fileInputStream);  
            while (fileInputStream.available() > 0) {  
                list.add((User) objectInputStream.readObject());  
            }  
            objectInputStream.close();  
 
        } catch (IOException e) {  
            e.printStackTrace();  
        } catch (ClassNotFoundException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
        User[] users = new User[list.size()];  
        return list.toArray(users);  
    }  
 
    public static void appendObjectsToFile(Object[] objs, String fileName)  
            throws FileNotFoundException {  
        File file = new File(fileName);  
        if (!file.exists())  
            throw new FileNotFoundException("未发现文件" + fileName);  
        try {  
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(  
                    new FileOutputStream(fileName, true)) {  
                // 如果要附加对象到文件后  
                // 必须重新定义这个方法  
                protected void writeStreamHeader() throws IOException {  
                }  
            };  
            for (Object obj : objs) {  
                objectOutputStream.writeObject(obj);  
            }  
            objectOutputStream.close();  
 
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
 
    }  

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;

public class ObjectStreamDemo {

public static void main(String args[]) {
User[] users = { new User("cater", 101), new User("justin", 102) };
// 写入新文件
writeObjectsToFile(users, args[0]);
try {
// 读取文件数据
users = readObjectsFromFile(args[0]);
// 显示读回的对象
for (User user : users) {
System.out.printf("%s\t%d%n", user.getName(), user.getNumber());
}
System.out.println();

users = new User[2];
users[0] = new User("momor", 103);
users[1] = new User("becky", 104);

// 附加新对象至文件
appendObjectsToFile(users, args[0]);

// 读取文件数据
users = readObjectsFromFile(args[0]);
// 显示读回的对象
for (User user : users) {
System.out.printf("%s\t%d\n", user.getName(), user.getNumber());
}

} catch (ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}

public static void writeObjectsToFile(Object[] objs, String filename) {
File file = new File(filename);
try {
ObjectOutputStream objectOutputStream = new ObjectOutputStream(
new FileOutputStream(file));
for (Object obj : objs) {
// 将对象写入文件
objectOutputStream.writeObject(obj);
}
objectOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public static User[] readObjectsFromFile(String fileName)
throws FileNotFoundException {
File file = new File(fileName);
// 如果文件不存在就丢出异常
if (!file.exists())
throw new FileNotFoundException("未找到文件" + fileName);
// 使用List先读取出对象
List<User> list = new ArrayList();
try {
FileInputStream fileInputStream = new FileInputStream(file);
ObjectInputStream objectInputStream = new ObjectInputStream(
fileInputStream);
while (fileInputStream.available() > 0) {
list.add((User) objectInputStream.readObject());
}
objectInputStream.close();

} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
User[] users = new User[list.size()];
return list.toArray(users);
}

public static void appendObjectsToFile(Object[] objs, String fileName)
throws FileNotFoundException {
File file = new File(fileName);
if (!file.exists())
throw new FileNotFoundException("未发现文件" + fileName);
try {
ObjectOutputStream objectOutputStream = new ObjectOutputStream(
new FileOutputStream(fileName, true)) {
// 如果要附加对象到文件后
// 必须重新定义这个方法
protected void writeStreamHeader() throws IOException {
}
};
for (Object obj : objs) {
objectOutputStream.writeObject(obj);
}
objectOutputStream.close();

} catch (IOException e) {
e.printStackTrace();
}

}
} 范例中必要的地方都已加上注释,虽然程序很长,但范例中已经将写入对象至文件、从文件读出对象、附加对象至文件的程序逻辑集中在writeObjectsToFile()、readObjectsFromFile()与appendObjectsToFile() 3个方法中

Java代码
Java代码
ObjectOutputStream objOutputStream =     
     new ObjectOutputStream(     
         new FileOutputStream(file, true)) {     
             protected void writeStreamHeader()     
                                  throws IOException {}     
         };   

ObjectOutputStream objOutputStream =  
     new ObjectOutputStream(  
         new FileOutputStream(file, true)) {  
             protected void writeStreamHeader()  
                                  throws IOException {}  
         }; 

2.6  BufferedInputStream
BufferedInputStream 为另一个输入流添加一些功能,即缓冲输入以及支持 mark 和 reset 方法的能力。在创建 BufferedInputStream 时,会创建一个内部缓冲区数组。在读取或跳过流中的字节时,可根据需要从包含的输入流再次填充该内部缓冲区,一次填充多个字节。mark 操作记录输入流中的某个点,reset 操作使得在从包含的输入流中获取新字节之前,再次读取自最后一次 mark 操作后读取的所有字节。
修改上面代码 :
Java代码
public class EnumerationInputStreamTest {  
 
    Enumeration         e    = null;       // 由内部类实现,如Vector  
    String              sss  = "testsetst";  
    SequenceInputStream seq  = null;  
    Vector              coll = null;  
 
    public void test() {  
        try {  
            long begin = System.currentTimeMillis();  
            System.out.println("开始::" + begin);  
            FileInputStream file = new FileInputStream("c:\\boot.ini");  
            BufferedInputStream fileBuffer = new BufferedInputStream(file);  
            ByteArrayInputStream byteArray = new ByteArrayInputStream(sss.getBytes());  
            BufferedInputStream byteArrayBuffer = new BufferedInputStream(byteArray);  
            coll = new Vector();  
            coll.add(fileBuffer);  
            coll.add(byteArrayBuffer);  
            e = ((Vector) coll).elements();  
            seq = new SequenceInputStream(e);  
            int i = 0;  
            while (i != -1) {  
                i = seq.read();  
                System.out.println("out:" + i);  
            }  
            long end = System.currentTimeMillis();  
            System.out.println("结束::" + end);  
            System.out.println("耗时::" + (end - begin));  
        } catch (FileNotFoundException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (IOException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
    }  
 
    public static void main(String... strings) {  
        EnumerationInputStreamTest eee = new EnumerationInputStreamTest();  
        eee.test();  
    }  
}  
 
运行结果:  
开始::1226545776404 
out:91 
out:98 
                    …  
out:-1    
结束::1226545776419 
耗时::15 

public class EnumerationInputStreamTest {

    Enumeration         e    = null;       // 由内部类实现,如Vector
    String              sss  = "testsetst";
    SequenceInputStream seq  = null;
    Vector              coll = null;

    public void test() {
        try {
            long begin = System.currentTimeMillis();
            System.out.println("开始::" + begin);
            FileInputStream file = new FileInputStream("c:\\boot.ini");
            BufferedInputStream fileBuffer = new BufferedInputStream(file);
            ByteArrayInputStream byteArray = new ByteArrayInputStream(sss.getBytes());
            BufferedInputStream byteArrayBuffer = new BufferedInputStream(byteArray);
            coll = new Vector();
            coll.add(fileBuffer);
            coll.add(byteArrayBuffer);
            e = ((Vector) coll).elements();
            seq = new SequenceInputStream(e);
            int i = 0;
            while (i != -1) {
                i = seq.read();
                System.out.println("out:" + i);
            }
            long end = System.currentTimeMillis();
            System.out.println("结束::" + end);
            System.out.println("耗时::" + (end - begin));
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public static void main(String... strings) {
        EnumerationInputStreamTest eee = new EnumerationInputStreamTest();
        eee.test();
    }
}

运行结果:
开始::1226545776404
out:91
out:98
                    …
out:-1
结束::1226545776419
耗时::15
2.7  PushbackInputStream
  用作缓冲数据,需要时可以将数据重新塞回流里面,相当于做了一个拦截和处理。
例子:

Java代码
public class PushBackTest {  
 
    String sss = "testsetst";  
    int    res[];  
    byte   byteArray[];  
 
    public void test() {  
        try {  
            long begin = System.currentTimeMillis();  
            System.out.println("开始::" + begin);  
            ByteArrayInputStream byteArrayStream = new ByteArrayInputStream("这只是个测试啊".getBytes());  
            BufferedInputStream byteArrayBuffer = new BufferedInputStream(byteArrayStream);  
            /* 
             * 这里必要时要设置pushback区大小,默认是1,如果长度太大,则会返回 java.io.IOException: Push back buffer is full 异常 
             */ 
            PushbackInputStream filePBack = new PushbackInputStream(byteArrayBuffer, 1024);  
 
            int intAvai = 0;  
            intAvai = filePBack.available();  
            System.out.println("intAvai:" + intAvai);  
            res = new int[intAvai + 1];  
            byteArray = new byte[intAvai];  
            int i = 0;  
            int j = 0;  
            while ((i = filePBack.read()) != -1) {  
                byteArray[j] = (byte) i;  
                System.out.println("out:" + i);  
                j++;  
            }  
            long end = System.currentTimeMillis();  
            System.out.println("结束::" + end);  
            System.out.println("耗时::" + (end - begin));  
            // ===================================  
            System.out.println("获取到的::" + byteArray);  
            filePBack.unread(byteArray);  
            i = 0;  
            System.out.println("filePBack.available():" + filePBack.available());  
            begin = System.currentTimeMillis();  
            System.out.println("重新开始::" + begin);  
 
            byte[] array = new byte[2];  
            int tmp = 0;  
            int count = 0;  
            while ((i = filePBack.read(array)) != -1) {  
                // 两个字节转换为整数  
                tmp = (short) ((array[0] << | (array[1] & 0xff));  
 
                tmp = tmp & 0xFFFF;  
 
                // 判断是否为BIG5,如果是则显示BIG5中文字  
                if (tmp > 0xA440 && tmp < 0xFFFF) {  
                    System.out.println("BIG5:" + new String(array));  
                } else {  
                    // 将第二个字节流推回  
                    if (count == 2) {  
                        filePBack.unread(array, 1, 1);  
                    }  
                    // 显示ASII范围的字符  
                    System.out.println("ASCII:" + (char) array[0]);  
                }  
            }  
            end = System.currentTimeMillis();  
            System.out.println("又结束::" + end);  
            System.out.println("再次耗时::" + (end - begin));  
             byteArrayStream.close();  
            byteArrayBuffer.close();  
            filePBack.close();  
        } catch (FileNotFoundException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (IOException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
    }  
 
    public static void main(String... strings) {  
        PushBackTest eee = new PushBackTest();  
        eee.test();  
    }  
}  
 
运行结果:  
开始::1226561001499 
…  
结束::1226561001499 
耗时::0   
…  
重新开始::1226561001499 
BIG5:这  
BIG5:只  
BIG5:是  
BIG5:个  
BIG5:测  
BIG5:试  
BIG5:啊  
又结束::1226561001499 
再次耗时::0 

public class PushBackTest {

    String sss = "testsetst";
    int    res[];
    byte   byteArray[];

    public void test() {
        try {
            long begin = System.currentTimeMillis();
            System.out.println("开始::" + begin);
            ByteArrayInputStream byteArrayStream = new ByteArrayInputStream("这只是个测试啊".getBytes());
            BufferedInputStream byteArrayBuffer = new BufferedInputStream(byteArrayStream);
            /*
             * 这里必要时要设置pushback区大小,默认是1,如果长度太大,则会返回 java.io.IOException: Push back buffer is full 异常
             */
            PushbackInputStream filePBack = new PushbackInputStream(byteArrayBuffer, 1024);

            int intAvai = 0;
            intAvai = filePBack.available();
            System.out.println("intAvai:" + intAvai);
            res = new int[intAvai + 1];
            byteArray = new byte[intAvai];
            int i = 0;
            int j = 0;
            while ((i = filePBack.read()) != -1) {
                byteArray[j] = (byte) i;
                System.out.println("out:" + i);
                j++;
            }
            long end = System.currentTimeMillis();
            System.out.println("结束::" + end);
            System.out.println("耗时::" + (end - begin));
            // ===================================
            System.out.println("获取到的::" + byteArray);
            filePBack.unread(byteArray);
            i = 0;
            System.out.println("filePBack.available():" + filePBack.available());
            begin = System.currentTimeMillis();
            System.out.println("重新开始::" + begin);

            byte[] array = new byte[2];
            int tmp = 0;
            int count = 0;
            while ((i = filePBack.read(array)) != -1) {
                // 两个字节转换为整数
                tmp = (short) ((array[0] << | (array[1] & 0xff));

                tmp = tmp & 0xFFFF;

                // 判断是否为BIG5,如果是则显示BIG5中文字
                if (tmp > 0xA440 && tmp < 0xFFFF) {
                    System.out.println("BIG5:" + new String(array));
                } else {
                    // 将第二个字节流推回
                    if (count == 2) {
                        filePBack.unread(array, 1, 1);
                    }
                    // 显示ASII范围的字符
                    System.out.println("ASCII:" + (char) array[0]);
                }
            }
            end = System.currentTimeMillis();
            System.out.println("又结束::" + end);
            System.out.println("再次耗时::" + (end - begin));
             byteArrayStream.close();
            byteArrayBuffer.close();
            filePBack.close();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public static void main(String... strings) {
        PushBackTest eee = new PushBackTest();
        eee.test();
    }
}

运行结果:
开始::1226561001499

结束::1226561001499
耗时::0

重新开始::1226561001499
BIG5:这
BIG5:只
BIG5:是
BIG5:个
BIG5:测
BIG5:试
BIG5:啊
又结束::1226561001499
再次耗时::0
3. 深入理解


二.OutputStream

三.Reader

四.Writer

你可能感兴趣的:(java,thread,Blog,J#)