黑马程序猿——25,打印流,合并流,对象序列化,管道流,RandomAccessFile
------<ahref="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流!
-------
黑马程序猿——25。打印流。合并流。对象序列化,管道流,RandomAccessFile
/*
IO流的打印流:专门用于打印的流
字节打印流PrintStream
PrintStream的构造函数能够接收file对象,String型字符串路径,字节输出流
字符打印流PrintWriter
PrintWriter的构造函数能够接收file对象,字符串路径。字节输出流,字符输出流
PrintWriter有刷新方法。写的时候记得刷新。
*/
import java.io.*; class Ioliou25 { public static void main(String[] args)throws IOException { File f=new File("f:\\yyyyyyyk.txt"); BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in)); // PrintWriter pw=new PrintWriter(System.out,true);//这个带true的就自己主动刷新,不用写flush方法了 //InputStreamReader是字节与字符的桥梁 //PrintWriter pw=new PrintWriter(f,true);//这样的写法编译错误,PrintWriter类没有这样的构造函数 /* PrintWriter构造函数里面能够带true的仅仅有 PrintWriter(OutputStream out,boolean autoFlush) PrintWriter(Writerout, boolean autoFlush) */ // PrintWriter pw=new PrintWriter(System.out); PrintWriter pw=new PrintWriter(new FileWriter(f),true);//使用FileWriter嵌套f的话就能够带true String s=null; while((s=bufr.readLine())!=null) { if(s.equals("over"))//设置结束语句 break; // pw.write(s.toUpperCase()); //没有换行 pw.println(s.toUpperCase());//这个使用println方法更为常见 //pw.flush(); } bufr.close(); pw.close(); } public static void soc(Object obj) { System.out.println(obj); } }
——————切割线————
/* 分割文件 */ import java.io.*; import java.util.*; class Ioliou27 { public static void main(String[] args)throws IOException { //qiege(); //hebing(); hebing2(); } publicstatic void qiege()/*分割文件*/throws IOException { File f=new File("f:\\8.11\\8.11练习.png");//建立文件对象 FileInputStream fis=new FileInputStream(f);//关联目的文件 FileOutputStream fos=null; int i=0,k=0; byte[] by=new byte[1024*10]; while((i=fis.read(by))!=-1) { k++; fos=new FileOutputStream("f:\\8.11\\8.11练习"+k+".part"); //每一次循环k值都不同所以相应有不同的关联的碎片文件 fos.write(by,0,i); } fis.close(); fos.close(); } public static void hebing()/*合并文件*/throws IOException { ArrayList<FileInputStream> al=new ArrayList<FileInputStream>(); //这里採用的是ArrayList集合 for(int x=1;x<=4;x++) { al.add(new FileInputStream("f:\\8.11\\8.11练习"+x+".part")); //把与文件相关联的流装进集合中 } final Iterator<FileInputStream> it= al.iterator(); //被匿名内部类訪问的局部成员要被final修饰 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("f:\\8.11\\8.11练习合并.png"); int i=0; byte[] by= new byte[1024]; while((i=sis.read(by))!=-1) { fos.write(by,0,i); } sis.close(); fos.close(); } public static void hebing2()/*另外一种合并方法*/throws IOException { Vector<FileInputStream> v=new Vector<FileInputStream>(); for(int x=1;x<=4;x++) { v.add(new FileInputStream("f:\\8.11\\8.11练习"+x+".part")); } Enumeration<FileInputStream> en=v.elements(); SequenceInputStream sis=new SequenceInputStream(en); FileOutputStream fos=new FileOutputStream("f:\\8.11\\8.11练习合并2.png"); int i=0; byte[] by=new byte[1024*10]; while((i=sis.read(by))!=-1) { fos.write(by,0,i); } sis.close(); fos.close(); } public static void soc(Object obj) { System.out.println(obj); } }
——————切割线——————
/*
对象的序列化
ObjectInputStream和ObjectOutputStream的使用。
序列化就是把对象储存在硬盘上。
*/
/*
实现了Serializable接口,那么该类会用uid号标识。
uid号与成员有关。
假设类中的成员发生变化,uid就会对应的发生变化。
当然也能够自己主动指定该类的固定uid
办法是在该类中加入:
public static final long serializableUID=42L;
当中举一个样例说明uid的作用:
第一次编译Per类所在java文件而产生的.class文件,
然后再编译执行主函数所在的java文件,把对象存储在硬盘上。
此时java会给Per类自己主动生成uid,由Per类生成的对象则是相应
也会有同样的uid
接着增删改Per类的成员。第二次编译Per类所在的java文件
而产生的.class文件相应的uid会变化的!第二次编译执行主函数
所在的java文件须要读取对象的时候就会报出执行异常。由于。
已经储存在硬盘里面的对象的uid号是第一次的uid号,Per类所在的
java文件第二次产生的.class文件的uid号与对象的uid号不同,所以
就会出现异常。
为了解决问题,在Per类中加入
public static final long serializableUID=42L;
就使得不管Per类怎么修改都仅仅有相应一个uid号。
Per类的对象uid号也是这个,Per类编译产生的.class文件uid号也是这个。
对象在硬盘上的写入和读取都相应同一个uid号。就不会发生异常了。
*/
import java.io.*; import java.util.*; class Ioliou28 { public static void main(String[] args)throws Exception { // xieru(); duqu() ; } public static void xieru() throws Exception { File f=new File("f:\\北方.txt"); FileOutputStream fos=new FileOutputStream(f); ObjectOutputStream oops=new ObjectOutputStream(fos); oops.writeObject(new Per("呼呼呼",26,"jkl")); //写入对象,写入的对象所属的类必须是实现了Serializable借口 oops.close(); } public static void duqu() throws Exception { File f=new File("f:\\北方.txt"); FileInputStream fos=new FileInputStream(f); ObjectInputStream oips=new ObjectInputStream(fos); Object obj=oips.readObject();//readObject方法返回的是Object类型的对象 //readObject方法会抛出一个ClassNotFoundException,为了简便。抛出都是Exception Per p =(Per)obj; oips.close(); soc(p); } public static void soc(Object obj) { System.out.println(obj); } } import java.io.*; import java.util.*; class Per implements Serializable { //public static final long serializableUID=42L; static String name="无名";//静态成员不能被序列化 private int age; transient String country="cn";//transient修饰的成员也不能被序列化 Per(String name, int age,String country) { this.name=name; this.age=age; this.country=country ; } public String toString() { return name+":"+age+":"+country; } }
——————切割线——————
/*
管道流:
PipedInputStream PipedOutputStream
管道输入流和管道输出流能够连接,与多线程密切相关。
通常是一条线程负责管道输入流,一条线程负责管道输出流。
*/
class Read() implements Runnable throws IOException { private PipedInputStream pis=null; Read(PipedInputStream pis) { this.pis=pis; } public void run() { int i=0; byte[] by=new byte[1024]; while((i=pis.read(by))!=-1) { //填写内容 } } } class Write() implements Runnable throws IOException { private PipedOutputStream pos=null; Write(PipedOutputStream pos) { this.pos=pos; } public void run( ) { // int i=0; // byte[] by=new byte[1024]; pos.write("huhuhu".getBytes()); } } import java.io.*; class Ioliou29 { public static void main(String[] args)throws IOException { PipedInputStream pis=new PipedInputStream(); PipedOutputStream pos=new PipedOutputStream(); pis.connect(pos);//管道输入流和管道输出流连接 Read r=new Read(pis); Write w=new Write(pos); Thread t1=new Thread(r); Thread t2=new Thread(w); t1.start(); t2.start(); } public static void soc(Object obj) { System.out.println(obj); } }
——————切割线——————
/*
RandomAccessFile类是IO包的成员
随机訪问,这个类应用的非常广。
里面封装了字节写入流和字节读取流,
所以具备了读写的功能,
可是仅仅是针对文件才干够进行操作,不能对路径进行操作。
操作文件还须要模式:
经常使用的两种模式:"r"仅仅读。"rw"读写。
该类里面还封装了很大的数组。另一个指针指示数组。
通过getFilePointer方法获得指针位置。
通过seek方法指定指针位置
*/
import java.io.*; class Ioliou30 { publicstatic void main(String[] args) throws IOException { write(); read(); } public static void write()throws IOException { File f=new File("f:\\学习.txt"); RandomAccessFile raf=new RandomAccessFile(f,"rw");//关联文件并确定操作模式 //假设文件不存在会自己主动创建 raf.write("一二三".getBytes()); raf.writeInt(56);//写入数字时最好用writeInt,以32位形式写入 raf.write("四五六".getBytes()); raf.writeInt(85);//写入数字时最好用writeInt,以32位形式写入 } public static void read()throws IOException { File f=new File("f:\\学习.txt"); RandomAccessFile raf=new RandomAccessFile(f,"rw");//关联文件并确定操作模式 soc("raf.getFilePointer()="+raf.getFilePointer());//getFilePointer方法返回内部数组指针位置 //raf.seek(2);//调整内部数组的指针指向第2位 byte[] by=new byte[4]; raf.read(by);//依照字节数组读取 String s=new String(by);//依照字节数组转成字符串 int i= raf.readInt();//依照32位读取数据 soc(s); soc(i); } public static void soc(Object obj) { System.out.println(obj); } }