黑马程序员——41,打印流,合并流,对象序列化,管道流,RandomAccessFile

----------- android 培训 java培训 、java学习型技术博客、期待与您交流!------------        
黑马程序员——41,打印流,合并流,对象序列化,管道流,RandomAccessFile    
一:打印流----》
        字节打印流PrintStream:其构造函数可以接收File对象,String型路径,字节流    
        字符打印流PrintWriter:其构造函数可以接收File对象,String型路径,字节流和字符流,应用更加广泛。
        所以主要介绍PrintWriter的使用,比较常用的构造函数有两个PrintWriter(OutputStream   out,boolean  autoFlush)和PrintWriter(Writer    out, boolean   autoFlush),一般后面填写的都是true,表示自动刷新。
 
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(Writer    out, 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);           
         }
}



二:合并流SquenceInputStream----》
        SequenceInputStream的构造函数有两个:
public   SequenceInputStream(Enumeration<? extends InputStream> e)//接收的是Enumeration的实例,该构造函数主要用在需要合并两个以上的读取流的情况下
public   SequenceInputStream(InputStream s1,InputStream s2)//按顺序接收读取流s1和s2(注意顺序不能调乱)


import java.io.*;
import java.util.*;
 
class  Ioliou27
{
         public  static void  main(String[] args)throws  IOException
         {
                      qiege();
                    //hebing();
                     hebing2();
 
         }
         public   static  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>()
                   {
                       //直接覆盖hasMoreElements和nextElement方法
                   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>();//直接用Vector集合来装流对象
                   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);        
         }
}



三:对象的序列化ObjectOutputStream----》
        对象序列化就是把对象存放在硬盘上,存放对象所属的类必须是实现了Serializable类。虚拟机会给实现了Serializable接口的类划分UID号标示,UID号与类成员有关,如果类成员有改变,虚拟机会重新划分UID号的,当然也可以自动在该类中添加固定的UID号:public  static   final   long   serialazableUID=42L;这样无论该类的成员怎么变化该类的UID号都是固定不变的。
       为什么会有这个UID号的存在?
       因为对象都是按照对象建立的,如果没有UID号的话,那么把一个类的对象存放在硬盘上,接着该类成员有所改变,程序再读取该对象的话,虚拟机就会容易混乱。
被static或者transient修饰的成员无法被序列化。
       调用readObject读取对象,调用writeObject写入对象。
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);            
         }
 
}
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;           
         }
}


四:管道流PipeInputStream和PipeOutputSatream----》
        管道输入流和管道输出流可以用connect方法连接在一起,通常与多线程密切相关:一般是一条线程负责管道输入流,一条线程负责管道输出流。
   
 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);//管道输入流和管道输出流连接
                 //开启线程
                   new  Thread(new  Read(pis)).start();
                   new  Thread(new   Write(pos)) .start();
               
         }
         public   static  void   soc(Object   obj)
         {
             System.out.println(obj);                  
         }
}


五:RandomAccessFile----》
        RandomAccessFile也是IO包的成员,里面封装了字节写入流和字节读取流,所以可以选取模式,常用的有两种模式”r”只读和”rw”读写,该类里面封装了一个非常大的数组,还有一个指针指示数组,通过getFilePointer方法获取指针位置,通过seek方法调整指针位置。
        有两个常用的构造函数,都是用来关联文件并且确定模式的:
public   RandomAccessFile(File file,  String  mode)throws FileNotFoundException
public   RandomAccessFile(String  name,String mode)throws FileNotFoundException
       由于该类方法很多,下面就列举一些比较常用的读取相关方法:

public   void close()throws  IOException   //关闭

public  int  read()throws  IOException //读取一个数据字节

public  int  read(byte[] b)throws  IOException //按照数组长度读取

public  int  read(byte[] b,int off,int len)throws  IOException//按照数组中实际接收数据的长度读取

public  final  boolean  readBoolean()throws  IOException//读取一个boolean

public  final  byte  readByte()throws  IOException//读取一个字节

public  final  char  readChar()throws  IOException//读取一个字符

public  final  double  readDouble()throws  IOException//读取一个double数据

public  final  float  readFloat()throws  IOException//读取一个float数据

public  final  int  readInt()throws IOException//读取一个int数据
        那么也有对应的写入方法,这里就不一一列举了。我们可以发现一个规律,那就是该类读取与写入都可以按照某个数据长度的进行操作的,非常的方便。
import   java.io.*;
class  Ioliou30
{
         public  static   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);         
         }
}


----------- android培训java培训、java学习型技术博客、期待与您交流!------------    


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值