java--io流-打印流,序列流,操作对象,管道流,RandomAccessFile,操作字节数组

来源:互联网 发布:数组正序遍历含义 编辑:程序博客网 时间:2024/05/21 18:36

打印流:

该流提供了打印方法,可以将各种数据类型的数据都原样打印。
字节打印流:
PrintStream
构造函数可以接收的参数类型:
1,file对象。File
2,字符串路径。String
3,字节输出流。OutputStream
字符打印流:
PrintWriter
构造函数可以接收的参数类型:
1,file对象。File
2,字符串路径。String
3,字节输出流。OutputStream
4,字符输出流,Writer。

import java.io.*;class  PrintStreamDemo{public static void main(String[] args) throws IOException{BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));PrintWriter out = new PrintWriter(new FileWriter("a.txt"),true);//PrintWriter out = new PrintWriter(System.out,true);String line = null;while((line=bufr.readLine())!=null){if("over".equals(line))break;out.println(line.toUpperCase());//out.flush();}out.close();bufr.close();}}
序列流:

SequenceInputStream 
表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。  
可以将多个流对象合并成一个流对象。
构造方法:
SequenceInputStream(InputStream s1, InputStream s2) ;通过记住这两个参数来初始化新创建的 SequenceInputStream(将按顺序读取这两个参数,先读取 s1,然后读取 s2),以提供从此 SequenceInputStream 读取的字节。
SequenceInputStream(Enumeration<? extends InputStream> e) ;通过记住参数来初始化新创建的 SequenceInputStream,该参数必须是生成运行时类型为 InputStream 对象的 Enumeration 型参数。

将1.txt,2.txt,3.txt合并成4.txt。

import java.util.*;import java.io.*;class  Test{public static void main(String[] args) throws IOException{Vector<FileInputStream> v=new Vector<FileInputStream>();v.add(new FileInputStream("1.txt"));v.add(new FileInputStream("2.txt"));v.add(new FileInputStream("3.txt"));Enumeration<FileInputStream> e=v.elements();SequenceInputStream sis=new SequenceInputStream(e);FileOutputStream fos=new FileOutputStream("4.txt");byte[] b=new byte[1024];int len;while((len=sis.read(b))!=-1){fos.write(b,0,len);}sis.close();fos.close();}}
切割文件

一个输入流对应多个输出流:

import java.io.*;import java.util.*;class SplitFile {public static void main(String[] args) throws IOException{splitFile();//切割merge();//再合并}public static void merge()throws IOException{ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();//ArrayList比Vector效率高for(int x=1; x<=3; x++){al.add(new FileInputStream("c:\\splitfiles\\"+x+".part"));}final Iterator<FileInputStream> it = al.iterator();Enumeration<FileInputStream> en = new Enumeration<FileInputStream>(){public boolean hasMoreElements(){return it.hasNext();}public FileInputStream nextElement(){return it.next();}};SequenceInputStream sis = new SequenceInputStream(en);FileOutputStream fos = new FileOutputStream("c:\\splitfiles\\0.bmp");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()throws IOException{FileInputStream fis =  new FileInputStream("c:\\1.bmp");FileOutputStream fos = null;byte[] buf = new byte[1024*1024];int len = 0;int count = 1;while((len=fis.read(buf))!=-1){fos = new FileOutputStream("c:\\splitfiles\\"+(count++)+".part");fos.write(buf,0,len);fos.close();}fis.close();}}

操作对象:
ObjectInputStream 与 ObjectOutputStream
被操作的对象需要实现Serializable(标记接口);

ObjectOutputStream 将 Java 对象的基本数据类型和图形写入 OutputStream。可以使用 ObjectInputStream 读取(重构)对象。

import java.util.*;import java.io.*;class  Test{public static void main(String[] args) throws Exception{writeObj();//写一个对象到文件中readObj();//从文件中读对象}public static void readObj()throws Exception{ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt"));Person p = (Person)ois.readObject();System.out.println(p);ois.close();}public static void writeObj()throws IOException{ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.txt"));oos.writeObject(new Person("lisi",39,"dy"));oos.close();}}class Person implements Serializable{public static final long serialVersionUID = 42L;//给类固定一个标识private String name;transient int age;//使非静态的变量也不可被序列化。static String country = "cn";//静态在方法区中,不可以被序列化。Person(String name,int age,String country){this.name = name;this.age = age;this.country = country;}public String toString(){return name+":"+age+":"+country;}}

管道流:

PipedInputStream和PipedOutputStream
输入输出可以直接连接,通过结合线程使用

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

import java.io.*;class Read implements Runnable{private PipedInputStream in;Read(PipedInputStream in){this.in = in;}public void run(){try{byte[] buf = new byte[1024];System.out.println("读取前。。没有数据阻塞");int len = in.read(buf);System.out.println("读到数据。。阻塞结束");String s= new String(buf,0,len);System.out.println(s);in.close();}catch (IOException e){throw new RuntimeException("管道读取流失败");}}}class Write implements Runnable{private PipedOutputStream out;Write(PipedOutputStream out){this.out = out;}public void run(){try{System.out.println("开始写入数据,等待6秒后。");Thread.sleep(6000);out.write("piped lai la".getBytes());out.close();}catch (Exception e){throw new RuntimeException("管道输出流失败");}}}class  PipedStreamDemo{public static void main(String[] args) throws IOException{PipedInputStream in = new PipedInputStream();PipedOutputStream out = new PipedOutputStream();in.connect(out);Read r = new Read(in);Write w = new Write(out);new Thread(r).start();new Thread(w).start();}}
RandomAccessFile

该类不是算是IO体系中子类。而是直接继承自Object。但是它是IO包中成员。因为它具备读和写功能。内部封装了一个数组,而且通过指针对数组的元素进行操作。可以通过getFilePointer获取指针位置,同时可以通过seek改变指针的位置。应用在多线程中。
完成读写的原理就是内部封装了字节输入流和输出流。
通过构造函数可以看出,该类只能操作文件。
而且操作文件还有模式:只读r,读写rw等。
如果模式为只读 r。不会创建文件。会去读取一个已存在文件,如果该文件不存在,则会出现异常。
如果模式rw。操作的文件不存在,会自动创建。如果存则不会覆盖。

Java API:此类的实例支持对随机访问文件的读取和写入。随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组。存在指向该隐含数组的光标或索引,称为文件指针;输入操作从文件指针开始读取字节,并随着对字节的读取而前移此文件指针。如果随机访问文件以读取/写入模式创建,则输出操作也可用;输出操作从文件指针开始写入字节,并随着对字节的写入而前移此文件指针。写入隐含数组的当前末尾之后的输出操作导致该数组扩展。该文件指针可以通过 getFilePointer 方法读取,并通过 seek 方法设置。

方法:
skipBytes();//跳过指定的字节数,只能往后跳。等

import java.io.*;class  Test{public static void main(String[] args) throws Exception{writeFile();writeFile_2();readFile();}public static void readFile()throws IOException //读取打印信息{RandomAccessFile raf = new RandomAccessFile("ran.txt","r");for(int i=0;i<11;i++){raf.seek(8*i);byte[] b=new byte[4];raf.read(b);String name=new String(b);int age=raf.readInt();System.out.println("name="+name+",age="+age);}raf.close();}public static void writeFile_2()throws IOException //写入信息2{RandomAccessFile raf = new RandomAccessFile("ran.txt","rw");raf.seek(8*10);//可以随便写位置,随便覆盖位置上的内容。raf.write("周期".getBytes());raf.writeInt(103);raf.close();}public static void writeFile()throws IOException //写入信息{RandomAccessFile raf = new RandomAccessFile("ran.txt","rw");raf.write("李四".getBytes());raf.writeInt(97);raf.write("王五".getBytes());raf.writeInt(258);raf.close();}}

DataInputStreamDataOutputStream

可以用于操作基本数据类型的数据的流对象。

oid writeUTF(String str) 以与机器无关方式使用 UTF-8 修改版编码将一个字符串写入基础输出流。

import java.io.*;class  Test{public static void main(String[] args) throws Exception{writeFile();read();Demo();}public static void Demo()throws IOException{DataOutputStream dos=new DataOutputStream(new FileOutputStream("UTFdemo.txt"));dos.writeUTF("发货个人规划的分割肉哥哥的非农赶紧的搜狗奇偶");dos.close();DataInputStream dis=new DataInputStream(new FileInputStream("UTFdemo.txt"));System.out.println(dis.readUTF());dis.close();}public static void read()throws IOException{DataInputStream dis=new DataInputStream(new FileInputStream("DataOutputStream.txt"));int num=dis.readInt();boolean b=dis.readBoolean();double d=dis.readDouble();System.out.println("num="+num);System.out.println("b="+b);System.out.println("d="+d);dis.close();}public static void writeFile()throws IOException //写入信息{DataOutputStream dos=new DataOutputStream(new FileOutputStream("DataOutputStream.txt"));dos.writeInt(2134);dos.writeBoolean(true);dos.writeDouble(3253.453);dos.close();}}
操作字节数组
ByteArrayInputStream :在构造的时候,需要接收数据源,而且数据源是一个字节数组。ByteArrayInputStream 包含一个内部缓冲区,该缓冲区包含从流中读取的字节。内部计数器跟踪 read 方法要提供的下一个字节。关闭 ByteArrayInputStream 无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException
ByteArrayOutputStream: 在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组。这就是数据目的地。此类实现了一个输出流,其中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray() 和 toString() 获取数据。关闭 ByteArrayOutputStream无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException

因为这两个流对象都操作的数组,并没有使用系统资源。所以,不用进行close关闭。
在流操作规律讲解时:
源设备,
键盘 System.in,硬盘 FileStream,内存 ArrayStream。
目的设备:
控制台 System.out,硬盘FileStream,内存 ArrayStream。
用流的读写思想来操作数据。

import java.io.*;class  Test{public static void main(String[] args) throws Exception{ByteArrayInputStream bis = new ByteArrayInputStream("ABCDEFD".getBytes());ByteArrayOutputStream bos = new ByteArrayOutputStream();int by = 0;while((by=bis.read())!=-1){bos.write(by);}System.out.println(bos.size());System.out.println(bos.toString());//bos.writeTo(new FileOutputStream("a.txt"));}}



0 0