IO包中的其他类
一、打印流
可直接操作输入流和文件
PrintWriter和PrintStream
与其他输出流不同,永远不会抛出IOException异常.为其他输出流添加功能,默认使用平台默认字符编码
可直接操作文件和流,比如PrintStream(String fileName)
二、序列流
SequenceInputStream
对多个流进行合并
被操作的对象需要实现Serializable(标记接口)
public static void marge() { /* *需求:将1.txt、2.txt、3.txt文件中的数据合并到一个文件中 */ /*可用 *Vector<FileInputStream> v=new Vector<FileInputStream>(); *v.add(new FileInputStream("1.txt")); *v.add(new FileInputStream("2txt")); *v.add(new FileInputStream("3.txt")); * Enumeration<FileInputStream> en=v.elements(); */ //如用ArrayList,它没有枚举,可用迭代器实现 ArrayList<FileInputStream> al=new ArrayList<FileInputStream>(); for(int i=1;i<=3;i++) { *al.add(new FileInputStream(x+".txt")); } /*用迭代器替代枚举 *final Iterator<FileInputStream> it=al.Iterator(); *自已定义枚举 *Enumeration<FileInputStream> en=new Enmeration<FileInputStream>() *{ *@Override * public boolean hasMoreElement() *{ * return it.hasNext(); *} * @Override * public FileInputStream nextElement() * { * return it.next(); *} *} */ //此句就是上面自定义的封装 Enumeration<FileInputStream> en=Collections.enumeration(al); SequenceInputStream sis=new SequenceInputStream(en); FileOutputStream fos=new FileOutputStream("4.txt"); byte [] buf=new byte[1024]; int len=0; while((len=sis.read(buf())!=-1) { fos.write(buf,0,len); } fos.close(); sis.close(); //序列流中所有的流都将关闭 }
实例:文件切割器
public static void splitFile(File file) throws IOException { //用读取流关联源文件 FileInputStream fis=new FileInputStream(file); byte[] buf=new byte[1024*1024]; FileOutputStream fos=null; int len=0; int count=1; File dir=new File("c:\\partfiles"); if (!dir.exists()) dir.mkdirs(); while(len=fis.read(buf))!=-1)) { fos=new FileOutputStream(new File(dir,(cout++)+".part")); fos.write(buf,0,len); } fis.close(); fos.close(); }
实例:合并文件
public static void mergeFile(File dir) { ArrayList<FileInputStream> al=new ArrayList<FileInputStream>(); for(int x=1;x<=3;x++) { al.add(new FileInputStream(new File(dir,x+".part"))); } Enumeration<FileInputStream> en=Collections.Enumeration(al); SequenceInputStream sis=new SequenceInputStream(en); FileOutputStream fos=new fileOutputStream(new File(dir,"1.bmp")); byte[] buf=new byte[1024]; int len=0; while((len=sis.read(buf))!=-1) { fos.write(buf,0,len); } fos.close(); sis.close(); }
三、操作对象
ObjectInputStream与ObjectOutputStream
被操作的对象需要实现Serializable(标记接口)
public class Person implements Serializable //类必须实现序列化接口 { public String name; public int age; } public static void writeObj() { ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("obj.object")); oos.write(new Person("小强",30)); //实现了序列化接口才可用 oos.close(); }
public static void readObj()
{
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("obj.object"));
Person p=(Person)ois.readObjet(); //必须要用有相应的Persion.class文件才能正确读取
System.out.priontln(p.getName()+":"+p.getAge());
ois.close();
}
Serializable序列化接口用于判断类和对象是否是同一版本,用serialVersionUID表示。
在反编译时,不同的系统可能serialVersionUID不一致,所以最好用private 显示声明一个serialVersionUID。
注意:静态属性和方法不会被序列化,如果对某非静态属性不想被序列化,可用transient标识。如:
private transient String name;
四、RandomAccessFile
随机访问文件,自身具备读写的方法。
通过skipBytes(int x),seek(int x)来达到随机访问。
它不是IO对象体系中的子类,它是Object的子类。
特点:
1. 该对象即能读,又能写。
2. 该对象内部维护了一个byte数组,并通过该指针可以操作数组中元素。
3. 可以通过getFilePointer方法获取指针的位置,和通过seek方法设置指针的位置。
4. 其实该对象就是将字节输入流和输出流进行了封装。
5.该对象的源或目的只能是文件,通过构造函数就可以看出。
public static void writeFile() throws IOException { //如果文件不存在,则创建;如果存在,则不创建 RandomAccessFile raf=new RandomAccessFile("ranacc.txt","rw"); raf.write("张三".getBytes()); raf.writeInt(97); raf.write("李四".getBytes()); raf.writeInt(102); raf.close(); } public static void readFile() { RandomAccessFile raf=new RandomAccessFile("ranacc.txt","r"); raf.seek(8); byte[] buf=new byte[4]; raf.read(buf); String name=new String(buf); Int age=readInt(); }
五、管道流
PipedInputStream和PipedOutputStream
输入输出可以直接进行连接,通过结合多线程使用,否则易死锁,因为管道输入和输出会阻塞。
前面的流输入流和输出流能过数组等对象进行连接,管道流的输入和输出能直接进行连接。
class Input implements Runnable { private PipedInputStream in; Input(PipeInputStream in) { this.in=in; } public void run() { try { byte[] byte=new byte[1024]; int len=in.read(ubf); String s=new String(buf,0,len); System.out.println("s="+s); in.close(); }catch (Exception e){ …… } } } class Oupput implements Runnable { private pipedOutputStream out; Output(PipeOutputStream out) { this.out=out; } public void run(){ try {
Thead.sleep(5000); out.write("hi,管道来了!".getBytes()); out.close(); } catch(Exception e){ …… } } } //使用 public static void main(String[] args) { PipedInputStream input=new PipedInputStream(); PipedOutputStream output=new PipedOutputStream(); input.connect(output); //多线程 new Thread(new Input(input)).start(); new Thread(new Output(output)).start(); }
六、操作基本数据类型
DataInputStream和DataOutputStream
允许应用程序将基本类型以适当形式写入流中。
public static void writeData() throws IOException { DataOutputStream dos=new DatasOutputStream(new FileOutputStream("data.txt")); dos.writeUTF("你好"); dos.close(); } public static void readData() throws IOException { DataInputStream dis=new DataInputStream(new FileInputStream("data.txt")); string Str=dis.readUTF(); System.out.println(str); }
七、操作字节数组
ByteArrayInputStream与ByteArrayOutputStream
源和目的都是内存,直接操作数组的流
被关闭是无效的,此类中的方法在关闭此流后仍可被调用,而不会产生任何IOException。因为它们没有调用底层资源,只是操作内存数据。
public static void operate() { ByteArrayInputStream bis=new ByteArrayInputStream("abcdef".getBytes()); ByteArrayOutputStream bos=new ByteArrayOutputStream(); int ch=0; while((ch=bis.read())!=-1) { bos.write(ch); } //无须关流 }
八、操作字符数组
CharArrayReader与CharArrayWrite
九、操作字符串
StringReader与StrinigWriter