javaI/0之[打印流][序列流/合并流/分割流][操作对象]等流对象

来源:互联网 发布:电脑机器码修改软件 编辑:程序博客网 时间:2024/05/21 11:00

1,打印流PrintWriter和PrintStream

/*打印流:该流提供了打印方法,可以将各种数据类型的数据都原样打印。字节打印流:PrintStream构造函数可以接收的参数类型:1,file对象。File2,字符串路径。String3,字节输出流。OutputStream字符打印流:PrintWriter构造函数可以接收的参数类型:1,file对象。File2,字符串路径。String3,字节输出流。OutputStream4,字符输出流,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);String line = null;while ((line = bufr.readLine()) != null) {if ("over".equals(line)){break;}out.println(line.toUpperCase());out.flush();}out.close();bufr.close();}}
2,SequenceInputStream序列流,对多个流进行合并。

import java.io.*;import java.util.*;class SequenceDemo {public static void main(String[] args) throws IOException {Vector<FileInputStream> v = new Vector<FileInputStream>();v.add(new FileInputStream("c:\\1.txt"));v.add(new FileInputStream("c:\\2.txt"));v.add(new FileInputStream("c:\\3.txt"));Enumeration<FileInputStream> en = v.elements();SequenceInputStream sis = new SequenceInputStream(en);FileOutputStream fos = new FileOutputStream("c:\\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();}}
3,SequenceInputStream序列流,对文件进行分割。

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>();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();}}
4,ObjectInputStream/ObjectOutputStream被操作的对象需要实现Serializable
import java.io.*;/* * 类通过实现Serializable接口以启用其序列化功能 * 未实现此接口的类将无法使其任何状态序列话或反序列化,可序列化类的所有子类都可以序列化 * 序列化接口没有方法或字段,仅用于标志可序列化的语义 */class Person implements Serializable{//如果没有这个标识,类编译后会生成一个UID,对应序列化对象中的UID也是这个//然后UID是根据类成员生成,这是如果将name属性的private改成public,那么在编译,UID就会发生改变//而此时,再读取时,序列化中的UID和class中的UID不一致,就会报错//自己给类加个标识,这个类改变了,但是序列化后的对象对应的UID没变,//class中对应的UID和序列化中的UID一致,就能使用public static final long serialVersionUID = 42L;private String name;//非静态成员不想序列化,加上关键字transient,age也没有序列化,虽然在堆内存中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;}}/* * ObjectInputStream和ObjectOutputStream * 被操作的对象需要实现Serializable, * 将堆内存中的数据存到硬盘中。序列话,串行化。 */import java.io.*;class ObjectStreamDemo {public static void main(String[] args) throws Exception{//writeObj();readObj();}public static void readObj()throws Exception{ObjectInputStream ois = new ObjectInputStream(new FileInputStream("c:\\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("c:\\obj.txt"));oos.writeObject(new Person("lisi0",399,"kr"));oos.close();}}
5,管道流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("读取前。。没有数据阻塞");//read是阻塞式方法,如果没有数据就一直阻塞,所以不建议管道输入输出流使用一个线程,容易造成死锁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("开始写入数据,等待2秒后。");Thread.sleep(2000);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);//这里不一定这俩线程哪个先执行,但是不管谁先谁后,read是个阻塞式方法,如果没数据的话得等,所以也只有write后才能读取了new Thread(r).start();new Thread(w).start();}}
6,RandomAccessFile
import java.io.*;/*RandomAccessFile该类很特殊,没有后缀(inputstream ,reader等)因为该类不是算是IO体系中子类。而是直接继承自Object。但是它是IO包中成员。因为它自身具备读和写功能。通过skipBytes(int x),seek(int x)来达到随即访问。内部封装了一个数组,而且通过指针对数组的元素进行操作。可以通过getFilePointer获取指针位置,同时可以通过seek改变指针的位置。其实完成读写的原理就是内部封装了字节输入流和输出流。通过构造函数可以看出,该类只能操作文件。而且操作文件还有模式:只读r,读写rw等。如果模式为只读 r。不会创建文件。会去读取一个已存在文件,如果该文件不存在,则会出现异常。如果模式rw。操作的文件不存在,会自动创建。如果存则不会覆盖文件,而是修改里面的数据,这个要注意。*/class RandomAccessFileDemo {public static void main(String[] args) throws IOException{//writeFile_2();//writeFile();readFile();//System.out.println(Integer.toBinaryString(258));}public static void readFile()throws IOException{RandomAccessFile raf = new RandomAccessFile("c:\\ran.txt","r");//调整对象中指针。//raf.seek(8*1);//跳过指定的字节数,只能往后跳,不能往前跳//raf.skipBytes(8);//一个中文俩字节,存入李四,占了前4个字节。byte[] buf = new byte[4];raf.read(buf);String name = new String(buf);//short age = raf.readShort();//0int age = raf.readInt();System.out.println("name="+name);System.out.println("age="+age);raf.close();}public static void writeFile_2()throws IOException{RandomAccessFile raf = new RandomAccessFile("ran.txt","rw");//直接在第48个字节开始写raf.seek(8*6);//raf.seek(8*0);如果前8个字节有数据,则将其覆盖raf.write("周期".getBytes());raf.writeInt(103);raf.close();}public static void writeFile()throws IOException{RandomAccessFile raf = new RandomAccessFile("c:\\ran.txt","rw");//raf.writeShort(1);//short占2个字节raf.write("李四".getBytes());raf.writeInt(97);//int占4个字节raf.write("王五".getBytes());raf.writeInt(99);raf.close();}}
7,DataInputStream与DataOutputStream操作基本数据类型
import java.io.*;class DataStreamDemo {public static void main(String[] args) throws IOException {// writeData();// readData();// writeUTFDemo();// readUTFDemo();}public static void readUTFDemo() throws IOException {DataInputStream dis = new DataInputStream(new FileInputStream("c:\\utf.txt"));String s = dis.readUTF();System.out.println(s);dis.close();}public static void writeUTFDemo() throws IOException {// 一般方法,如果是普通的,要用你普通的读,如果用修改版的,则用修改版的读取,否则因为内部实现的机制不一样,会造成字节数不同,读取结果出问题// OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk.txt"),"gbk");// osw.write("你好");// osw.close();DataOutputStream dos = new DataOutputStream(new FileOutputStream("c:\\utfdate.txt"));// 修改版,用UTF,参看APIdos.writeUTF("你好");dos.close();}public static void readData() throws IOException {DataInputStream dis = new DataInputStream(new FileInputStream("c:\\data.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 writeData() throws IOException {DataOutputStream dos = new DataOutputStream(new FileOutputStream("c:\\data.txt"));dos.writeInt(234);dos.writeBoolean(true);dos.writeDouble(9887.543);dos.close();}}

8,ByteArrayInputStream与ByteArrayOutputStream操作字节数组

/*用于操作字节数组的流对象。ByteArrayInputStream :在构造的时候,需要接收数据源。而且数据源是一个字节数组。ByteArrayOutputStream: 在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组。这就是数据目的地。因为这两个流对象操作的都是内存数组,并没有使用系统资源。所以,不用进行close关闭。在流操作规律讲解时:源设备,键盘 System.in,硬盘 FileStream,内存 ArrayStream。目的设备:控制台 System.out,硬盘FileStream,内存 ArrayStream。用流的读写思想来操作数据。*/import java.io.*;class ByteArrayStream {public static void main(String[] args) {//数据源。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"));}}

9,操作字符编码问题

import java.io.*;class EncodeStream {public static void main(String[] args) throws IOException {//writeText();readText();}public static void readText()throws IOException {//InputStreamReader isr = new InputStreamReader(new FileInputStream("c:\\utf.txt"),"gbk");InputStreamReader isr = new InputStreamReader(new FileInputStream("c:\\utf.txt"),"UTF-8");char[] buf = new char[10];int len = isr.read(buf);String str = new String(buf,0,len);System.out.println(str);isr.close();}public static void writeText()throws IOException {OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("c:\\utf.txt"),"UTF-8");osw.write("你好");osw.close();}}
/*编码:字符串变成字节数组。解码:字节数组变成字符串。String-->byte[];     str.getBytes(charsetName);byte[] -->String:    new String(byte[],charsetName);*/import java.util.*;class  EncodeDemo{public static void main(String[] args)throws Exception {String s = "哈哈";byte[] b1 = s.getBytes("GBK");System.out.println(Arrays.toString(b1));String s1 = new String(b1,"utf-8");System.out.println("s1="+s1);//对s1进行iso8859-1编码。byte[] b2 = s1.getBytes("utf-8");System.out.println(Arrays.toString(b2));String s2 = new String(b2,"gbk");System.out.println("s2="+s2);}}

/*UTF-8 修改版DataInput 和 DataOutput 接口的实现表示稍作改版的 UTF-8 格式的 Unicode 字符串。(关于标准 UTF-8 格式的信息,请参阅 The Unicode Standard, Version 4.0 的 3.9 Unicode Encoding Forms 节)。注意,在下表中,最高有效位显示在最左边的列中。 '\u0001' 到 '\u007F' 范围内的所有字符都是用单个字节表示的:  位值 字节 1 0 位 6-0  null 字符 '\u0000' 以及从 '\u0080' 到 '\u07FF' 的范围内的字符用两个字节表示:  位值 字节 1 1 1 0 位 10-6  字节 2 1 0 位 5-0  '\u0800' 到 '\uFFFF' 范围内的 char 值用三个字节表示:  位值 字节 1 1 1 1 0 位 15-12  字节 2 1 0 位 11-6  字节 3 1 0 位 5-0  这种格式与标准 UTF-8 格式之间的不同如下: null 字节 '\u0000' 是用 2-byte 格式而不是 1-byte 格式编码的,因此已编码的字符串中决不会有嵌入的 null。 仅使用 1-byte、2-byte 和 3-byte 格式。 增补字符是以代理项对的形式表示的。 */class EncodeDemo2 {public static void main(String[] args) throws Exception{//记事本中只写联通俩字,但是打开后发现是乱码,原因如下://写入的编码是别的一种编码,但是,在解码时出问题了//UTF-8编码有个头文件,如果是一个字符用单个字节表示,头文件是0//如果一个字符是用两个,头文件是110  10//三个的话对比如下//但是在将“联通”俩字以GBK保存后,占用的字节头文件刚好符合UTF-8,那么打开时,就默认为UTF-8形式打开了,就出错了。只有这俩字特殊//"你联通啊"这样就可以,加点文字,让你头文件不满足UTF-8即可。String s = "联通";byte[] by = s.getBytes("gbk");for(byte b : by){System.out.println(Integer.toBinaryString(b));//有效位System.out.println(Integer.toBinaryString(b&255));}System.out.println("Hello World!");}}




















0 0
原创粉丝点击