黑马程序员_IO流

------- android培训java培训、期待与您交流! ----------

 
一、概述
     文件通常是由一连串的字节或字符构成,组成文件的字节序列称为字节流;组成文件的字符序列称为字符流。Java 中根据流的方向可以分为输入流和输出流。输入流是将文件或其它输入设备的数据加载到内存的过程;输出流恰恰相反,是将内存中的数据保存到文件或其他输出设备。

     IO流泛指对某个设备或环境进行数据的数据或输出。
     数据的最常见体现形式是:文件。
InputStream 和OutputStream(字节流

Reader 和Writer(字符流)
     
二、文件流
     1、FileWriter(文件字符输入流)
          创建文件
          
package   com.File;

import   java.io.*;

public   class   FileWriterDemo {

      public   static   void   main(String[] args){
             //创建一个FileWriter对象。该对象一被初始化就必须要明确被操作的文件。
          FileWriter fw =   null ;
          
             try   {
                 //而且该文件会被创建到指定目录下。如果该目录下已有同名文件,将被覆盖。
                 //其实该步就是在明确数据要存放的目的地。
              fw =   new   FileWriter( "demo.txt"   );
              
                 //如果想对已有文件进行数据续写,创建文件时传递一个true参数,代表不覆盖已有的文件。并在已有文件的末尾处进行数据续写。
                 //fw = new FileWriter("demo.txt",true);
                 //调用write方法,将字符串写入到流中。
              fw.write(   "JAVA Hello" );
          }   catch   (IOException e) {
              
              System.   out .println( "catch:"   +e.toString());
          }   finally {
              
                      try   {
                           //关闭流资源,但是关闭之前会刷新一次内部的缓冲中的数据。
                           //将数据刷到目的地中。
                           //fw.flush();
                           //和flush区别:flush刷新后,流可以继续使用,close刷新后,会将流关闭。
                           if (fw !=   null   )
                             fw.close();
                   }   catch   (IOException e) {
                        
                        System.   out .println(e.toString());

          }
          
     }

}
     
          既然close方法也可以刷新缓冲区,为什么,还要专门有一个flush方法。

               jvm占用空间有限,不可能让一个比较大的数据完毕后,才刷新缓冲区。

          close方法和flush方法的区别?

              flush:刷新缓冲区,流对象还可以继续使用。
              close:先刷新缓冲区,然后释放资源。流对象不可以被使用了

     
     2、FileReader(文件字符输入流)
          
package   com.File;

import   java.io.*;

public   class   FileReaderDemo {

     
      public   static   void   main(String[] args) {
             //创建一个文件读取流对象,和指定名称的文件相关联。
             //要保证该文件是已经存在的,如果不存在,会发生异常FileNotFoundException
          FileReader fr =   null ;
             try   {
              fr =   new   FileReader(   "demo.txt" );
              
                 //定义一个字符数组。用于存储读到字符。
                 //该read(char[])返回的是读到字符个数。
                 char [] buf =   new       char [1024];
                 int   ch = 0;
                 //调用读取流对象的read方法。
                 //read():一次读一个字符。而且会自动往下读。
                 while ((ch=fr.read(buf))!=-1){
                      //将char数组有效部分转换成字符串
                   System.   out .println( new   String(buf,0,ch));
              }
          }   catch   (FileNotFoundException e) {
              
              System.   out .println(e.toString());
          }   catch   (IOException e) {
                 //   TODO   Auto-generated catch block
              System.   out .println(e.toString());
          }   finally {
                 if (fr !=   null   )
                      try   {
                        fr.close();
                   }   catch   (IOException e) {
                        
                        System.   out .println(e.toString());
                   }
          }
     }

}

     3、FileInputStream(文件字节输入流)和FileOutStream(文件字节输出流)
          基本操作和字符流类型相同,但它不仅可以操作字符,还可以操作其他媒体文件,例如Copy一个Jpg或者Mp3文件。字节流可以不用刷新,因为数据的最基本单位就是字节,所以,可以直接把字节数据写入文件。

     需求:将一个文本文件复制一份。

          
package   com.File;

import   java.io.*;

public   class   CopyDemo {

      public   static   void   main(String[] args)   throws   IOException {
             //   TODO   Auto-generated method stub
           copy_1();
           copy_2();
     }
      //字节方法
      private   static   void   copy_2()   throws   IOException {
             //创建输入流
          FileInputStream fis =   new   FileInputStream( "demo.txt"   );

             //创建输出流
           FileOutputStream fos =   new   FileOutputStream( "demo_2.txt" );
          
             byte [] bytes =   new   byte [1024];
             int   num = 0;
             while ((num=fis.read(bytes)) != -1){
              fos.write(bytes,0,num);
          }
     }
      //字符方法
      private   static   void   copy_1()   throws   IOException {
          
          FileReader fr =   null ;
          FileWriter fw =   null ;
          
          fr =   new   FileReader( "demo.txt"   );
          fw =   new   FileWriter( "demo_1.txt"   );
              
             char [] chars =   new   char [1024];
             int   num = 0;
              
             while ((num = fr.read(chars)) != -1){
              fw.write(chars,0,num);
              
          }    
          fw.flush();
     
          fr.close();
          fw.close();
     
     }
     
}
     
三、缓冲流
      为了提高效率而存在的, 减少物理读取次数, 缓冲流主要有: BufferedInputStream 、BufferedOutputStream 、BufferedReader 、BufferedWriter , 并且 BufferedReader 提供了实用方法readLine(),可以直接读取一行,BufferWriter 提供了newLine() 可以写换行符。

     1、 采用字符缓冲流改造文件复制代码
     
package   com.File;

import   java.io.*;

public   class   CopyDemo02 {

      public   static   void   main(String[] args)   throws   IOException {
          
           copy_1();
     }
     
      //字符方法
      private   static   void   copy_1()   throws   IOException {
          
          BufferedReader br =   null ;
          BufferedWriter bw =   null ;
          
          br =   new   BufferedReader( new   FileReader( "demo.txt"   ));
          bw =   new   BufferedWriter( new   FileWriter( "demo_b1.txt"   ));
              
          
          String num =   null ;
              
             while ((num = br.readLine()) !=   null ){
              bw.write(num);
              bw.newLine();
              
          }    
     
          br.close();
          bw.close();
     
     }
     
}


     2、装饰设计模式:

当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有的功能,并提供加强功能。那么自定义的该类称为装饰类。

装饰类通常会通过构造方法接收被装饰的对象。并基于被装饰的对象的功能,提供更强的功能。

装饰模式比继承要灵活。避免了继承体系臃肿。而且降低了类于类之间的关系。装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强功能。所以装饰类和被装饰类通常是都属于一个体系中的。

例:
package   com.File;

import   java.io.*;
class   MyBufferedReader   extends   Reader
{
     
      private   Reader   r ;
     MyBufferedReader(Reader r)
     {
             this . r   = r;
     }
     
      //模拟一下BufferedReader的readLine方法
      //可以一次读一行数据的方法。
      public   String myReadLine()   throws   IOException
     {
             //定义一个临时容器。原BufferReader封装的是字符数组。
             //为了演示方便。定义一个StringBuilder容器。因为最终还是要将数据变成字符串。
          StringBuilder sb =   new   StringBuilder();
             int   ch = 0;
             while ((ch= r   .read())!=-1)
          {
                 if (ch== '\r'   )
                      continue ;
                 if (ch== '\n'   )
                      return   sb.toString();
                 else
                   sb.append((   char )ch);
          }

             if (sb.length()!=0)
                 return   sb.toString();
             return   null   ;       
     }

      /*
     覆盖Reader类中的抽象方法。

     */
      public   int   read( char   [] cbuf,   int   off,   int   len)   throws   IOException
     {
             return   r   .read(cbuf,off,len) ;
     }

      public   void   close() throws   IOException
     {
             r .close();
     }
      public   void   myClose() throws   IOException
     {
             r .close();
     }
}

package  com.File;

import  java.io.*;

//装饰类
class  MyLineNumberReader  extends  MyBufferedReader
{
       private   int   lineNumber  ;
     MyLineNumberReader(Reader r)
     {
            super  (r);
     }
       //增强myReadLine方法,为其增加行号
       public  String myReadLine()  throws  IOException
     {

            lineNumber  ++;
            return   super  .myReadLine();
     }
       public   void  setLineNumber(  int  lineNumber)
     {
            this  . lineNumber  = lineNumber;
     }
       public   int  getLineNumber()
     {
            return   lineNumber  ;
     }
}

public   class    MyLineNumberReaderDemo
{
       public   static   void  main(String[] args)  throws  IOException
     {
          FileReader fr =  new  FileReader( "AbstractDemo.java"  );

          MyLineNumberReader mylnr =  new  MyLineNumberReader(fr);

          String line =  null  ;
            //mylnr.setLineNumber(100);//设置行号的初始值
            while  ((line=mylnr.myReadLine())!=  null )
          {
               System.  out  .println(mylnr.getLineNumber()+ "::"  +line);
          }

          mylnr.myClose();
     }
}
LineNumberReader(Reader in)//使用默认输入缓冲区的大小创建新的行编号 reader。LineNumberReader此类定义了方法 setLineNumber(int)getLineNumber(),它们可分别用于设置和获取当前行号。

四、转换流
       主要有两个:
            InputStreamReader 主要是将字节流输入流转换成字符输入流
            OutputStreamWriter 主要是将字节流输出流转换成字符输出流

     1、 InputStreamReader  。需求:将键盘录入的字节流转换成字符流
     
package   com.File;

import   java.io.*;

public   class   TransStreamDemo {

      public   static   void   main(String[] args)   throws   IOException {
             //获取键盘录入对象。
          InputStream in = System.   in ;

             //将字节流对象转成字符流对象,使用转换流。InputStreamReader
          InputStreamReader isr =   new   InputStreamReader(in);
             //为了提高效率,将字符串进行缓冲区技术高效操作。使用BufferedReader
          BufferedReader bufr =   new   BufferedReader(isr);
          
          String line =   null ;
             while ((line=bufr.readLine())!= null ){
                 if ( "over"   .equals(line)){
                      break ;
              }
              System.   out .println(line.toUpperCase());
              
          }
          bufr.close();
     }

}


     2、   OutputStreamWriter
package   com.File;

import   java.io.*;

public   class   TransStreamDemo {

      public   static   void   main(String[] args)   throws   IOException {
             //获取键盘录入对象。
             //InputStream in = System.in;

             //将字节流对象转成字符流对象,使用转换流。InputStreamReader
             //InputStreamReader isr = new InputStreamReader(in);
             //为了提高效率,将字符串进行缓冲区技术高效操作。使用BufferedReader
             //BufferedReader bufr = new BufferedReader(isr);
          
          BufferedReader bufr =   new   BufferedReader( new   InputStreamReader(System. in   ));
          
             //OutputStream out = System.out;
             //OutputStreamWriter osw = new OutputStreamWriter(out);
          
             //BufferedWriter bufw = new BufferedWriter(osw);// 为使用newLine
          
          BufferedWriter bufw =   new   BufferedWriter( new   OutputStreamWriter(System. out   ));
          
          String line =   null ;
             while ((line=bufr.readLine())!= null ){
                 if ( "over"   .equals(line)){
                      break ;
              }
              bufw.write(line.toUpperCase());
              bufw.newLine();
                 //字符输出有缓存区,需要flush
              bufw.flush();
              
          }
          bufr.close();
     }

}


五、 流操作的基本规律

     通过三个明确来完成:
1,明确源和目的。
     源:输入流。InputStream  Reader
     目的:输出流。OutputStream  Writer。
2,操作的数据是否是纯文本。
     是:字符流。
     不是:字节流。

3,当体系明确后,在明确要使用哪个具体的对象。
     通过设备来进行区分:
     源设备:内存,硬盘。键盘
     目的设备:内存,硬盘,控制台。
     
1、需求分析:将一个文本文件中数据存储到另一个文件中。复制文件。

            源:因为是源,所以使用读取流。InputStream Reader 
     是不是操作文本文件。
     是!这时就可以选择Reader
     这样体系就明确了。
     接下来明确要使用该体系中的哪个对象。
     明确设备:硬盘。上一个文件。
     Reader体系中可以操作文件的对象是 FileReader
     是否需要提高效率:是!。加入Reader体系中缓冲区 BufferedReader.

     FileReader fr = new FileReader("demo.txt");
     BufferedReader bufr = new BufferedReader(fr);



     目的:OutputStream Writer
     是否是纯文本。
     是!Writer。
     设备:硬盘,一个文件。
     Writer体系中可以操作文件的对象FileWriter。
     是否需要提高效率:是!。加入Writer体系中缓冲区 BufferedWriter
    
     FileWriter fw = new FileWriter("b.txt");
     BufferedWriter bufw = new BufferedWriter(fw);

     2、需求:将键盘录入的数据保存到一个文件中。

     源:InputStream Reader
     是不是纯文本?是!Reader
    
     设备:键盘。对应的对象是System.in.
     不是选择Reader吗?System.in对应的不是字节流吗?
     为了操作键盘的文本数据方便。转成字符流按照字符串操作是最方便的。
     所以既然明确了Reader,那么就将System.in转换成Reader。
     用了Reader体系中转换流,InputStreamReader
     InputStreamReader isr = new InputStreamReader(System.in);
     需要提高效率吗?需要!BufferedReader
     BufferedReader bufr = new BufferedReader(isr);


     目的:OutputStream  Writer
     是否是存文本?是!Writer。
     设备:硬盘。一个文件。使用 FileWriter。
     FileWriter fw = new FileWriter("c.txt");
     需要提高效率吗?需要。
     BufferedWriter bufw = new BufferedWriter(fw);


3、扩展一下,想要把录入的数据按照指定的编码表(utf-8),将数据存到文件中。
    
     目的:OutputStream  Writer
     是否是存文本?是!Writer。
     设备:硬盘。一个文件。使用 FileWriter。
     但是FileWriter是使用的默认编码表。GBK.
    
     但是存储时,需要加入指定编码表utf-8。而指定的编码表只有转换流可以指定。
     所以要使用的对象是OutputStreamWriter。
     而该转换流对象要接收一个字节输出流。而且还可以操作的文件的字节输出流。FileOutputStream
     OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d.txt"),"UTF-8");
     需要高效吗?需要。
     BufferedWriter bufw = new BufferedWriter(osw);


     所以,记住。转换流什么使用。字符和字节之间的桥梁,通常,涉及到字符编码转换时,需要用到转换流。

六、File
      用来将文件或者文件夹封装成对象, 方便对文件与文件夹的属性信息进行操作 。File 对象可以作为参数传递给流的构造函数。

     File类常见方法:
1,创建。
     boolean createNewFile():在指定位置创建文件,如果该文件已经存在,则不创建,返回false。和输出流不一样,输出流对象一建立创建文件。而且文件已经存在,会覆盖。
     boolean mkdir():创建文件夹。
     boolean mkdirs():创建多级文件夹。
2,删除。
     boolean delete():删除失败返回false。如果文件正在被使用,则删除不了返回falsel。
     void deleteOnExit();在程序退出时删除指定文件。

3,判断。
     boolean exists() :文件是否存在.
     isFile():
     isDirectory();
     isHidden();
     isAbsolute();

4,获取信息。
     getName():
     getPath():
     getParent():
     getAbsolutePath()
     long lastModified()
     long length() 

需求:列出指定目录下文件或者文件夹,包含子目录中的内容。(以及删除)
package   com.File;
import   java.io.*;
public   class   listFile {

      public   static   void   main(String[] args) {
          File dir =   new   File(   "F:\\360云盘\\视频\\51CTO下载-毕向东上课PPT源码"   );
             //showDir(dir ,0);

           removeDir( new   File(   "F:\\客户端\\zzz"   ));
     }
      public   static   String getLevel( int   level)
     {
          StringBuilder sb =   new   StringBuilder();
          sb.append(   "|--" );
             for ( int   x=0; x<level; x++)
          {
                 //sb.append("|--");
              sb.insert(0,   "|  " );

          }
             return   sb.toString();
     }
      public   static   void   showDir(File dir, int   level)
     {
          
          System.   out .println(getLevel(level)+dir.getName());

          level++;
          File[] files = dir.listFiles();
             for ( int   x=0; x<files. length ; x++)
          {
                 if (files[x].isDirectory())
                    showDir(files[x],level);
                 else
                   System.   out .println(getLevel(level)+files[x]);
          }
          
     }
     
      public   static   void   removeDir(File dir)
     {
          File[] files = dir.listFiles();
          
             for ( int   x=0; x<files. length ; x++)
          {
                 if (files[x].isDirectory()) //判断是否是目录
                    removeDir(files[x]);
                 else
                   System.   out .println(files[x].toString()+ ":-file-:"   +files[x].delete()); //打印并删除文件
          }

          System.   out .println(dir+ "::dir::"   +dir.delete()); //删除目录
     }

}

七、Properties
是hashtable的子类。它具备map集合的特点。而且它里面存储的键值对都是字符串。是集合中和IO技术相结合的集合容器。

该对象的特点:可以用于键值对形式的配置文件。

在加载数据时,需要数据有固定格式:键=值。
例:
    
          Properties prop = new Properties();
          FileInputStream fis = new FileInputStream("info.txt");

          //将流中的数据加载进集合。
          prop.load(fis);

          prop.setProperty("wangwu","39");

          FileOutputStream fos = new FileOutputStream("info.txt");

          prop.store(fos,"haha");

          prop.list(System.out);

          fos.close();
          fis.close();

八、打印流
     该流提供了打印方法,可以将各种数据类型的数据都原样打印。

字节打印流:
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);

          String line = null;

          while((line=bufr.readLine())!=null)
          {
               if("over".equals(line))
                    break;
               out.println(line.toUpperCase());
               //out.flush();
          }

          out.close();
          bufr.close();

     }    
}
 
九、序列流(SequenceInputStream)
     对多个流进行合并。
     
          应用图片的合成
package   com.File;

import   java.io.*;
import   java.util.ArrayList;
import   java.util.*;

public   class   SequenceInputStreamDemo {


      public   static   void   main(String[] args)   throws   IOException {
           splitFile();
           merge();
     }
     
     
      //分割文件
      public   static   void   splitFile()   throws   IOException{
          FileInputStream fis =   new   FileInputStream( "D:\\360\\360Downloads\\wpcache\\360wallpaper.jpg"   );
          FileOutputStream fos =   null ;
          
             byte [] buf =   new   byte [1024*100];
          
             int   len = 0;
             int   count = 0;
             while ((len=fis.read(buf))!=-1){
              fos =   new   FileOutputStream( "D:\\360\\360Downloads\\wpcache\\"   +(count++)+ ".suipian" );
              fos.write(buf,0,len);
              fos.close();
          
          }
          fis.close();
     }
     

      //合并
      public   static   void   merge()   throws   IOException{
          ArrayList<FileInputStream> al =   new   ArrayList<FileInputStream>();
          
             for ( int   x=0;x<3; x++){
              al.add(   new   FileInputStream( "D:\\360\\360Downloads\\wpcache\\"   +x+ ".suipian"   ));
          }
          
             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( "D:\\360\\360Downloads\\wpcache\\hebing.bmp"   );
          
             byte [] buf =   new   byte [1024];
             int   len = 0;
             while ((len=sis.read(buf))!=-1){
              fos.write(buf, 0, len);
          }
          fos.close();
          sis.close();
     }
     
     
}

十、对象流
     对象流可以将Java 对象转换成二进制写入磁盘,这个过程通常叫做   序列化  ,并且还可以从磁盘读出完整的Java 对象,而这个过程叫做   反序列化  。
     对象流主要包括:ObjectInputStream 和ObjectOutputStream
        序列化 必须实现序列化接口java.io. Serializable ,该接口没有任何方法, 只是一种 标记接口 ,标记这个类是可以序列化的
     序列化是对内存中的数据。
     静态不能被序列换

     
package   com.File;

import   java.io.*;

public   class   ObjectStreamDemo
{
      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( "lisi0"   ,399, "kr"   ));

          oos.close();
     }
}

//实现Serializable接口,标记这个类是可以序列化的
class   Person   implements   Serializable{
      //定义类的序列号
      public   static   final   long   serialVersionUID   = 42L;

      private   String   name ;
      //采用transient 关键字修饰此属性,序列化时会忽略
      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
           输入输出可以直接进行连接,通过结合线程使用
  
package   com.File;
import   java.io.*;

class   Read   implements   Runnable{
      private   PipedInputStream   in ;
     Read(PipedInputStream in){
             this . in   = in;
     }
      @Override
      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;
     }
      @Override
      public   void   run() {
          System.   out .println( "开始写入数据,等待6秒后"   );
             try   {
              Thread. sleep(6000);
                 out .write(   "piped lai la" .getBytes());
                 out .close();
          }   catch   (Exception e) {
                 throw   new   RuntimeException( "管道流输出失败" );
          }
          
          
     }
}
public   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。操作的文件不存在,会自动创建。如果存则不会覆盖
     
import java.io.*;

class RandomAccessFileDemo
{
     public static void main(String[] args) throws IOException
     {
          //writeFile_2();
          //readFile();

          //System.out.println(Integer.toBinaryString(258));

     }

     public static void readFile()throws IOException
     {
          RandomAccessFile raf = new RandomAccessFile("ran.txt","r");
         
          //调整对象中指针。
          //raf.seek(8*1);

          //跳过指定的字节数
          raf.skipBytes(8);

          byte[] buf = new byte[4];

          raf.read(buf);

          String name = new String(buf);

          int 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");
          raf.seek(8*0);
          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(99);

          raf.close();
     }
}

十三、字符编码:
        计算机底层是没有文本文件、图片文件之分的,它只记录每个文件的二进制序列。
        常见的码表:
            ASCII:美国标准信息交换码,用一个字节的7位可以表示。
            ISO8859-1:拉丁码表。欧洲码表用一个字节的8位表示。
            GB2312:中国的中文编码表。
            GBK:中国的中文编码表升级,融合了更多的中文文字符号。
            Unicode:国际标准码,融合了多种文字。
            UTF-8:最多用三个字节来表示一个字符。
        字符流的出现方便操作字符,更重要的是加入了编码转换,通过转换流来完成的
            InputStreamReader和OutputStreamWriter
        举例说明:
            package com.itheima.encode;           
            import java.io.FileInputStream;
            import java.io.FileOutputStream;
            import java.io.IOException;
            import java.io.InputStreamReader;
            import java.io.OutputStreamWriter;

            /*
             * 基本的字符和字节流是实现不了编码问题的。
             * 如果你想实现编码的处理,就必须使用转换流。
             * OutputStreamWriter:如果没有指定编码,默认编码是GBK。
             * 字符流 = 字节符 + 编码表
             * 编码问题的解决方案:采用统一编码表。
             */
            public class EncodeStream {
                public static void main(String[] args) throws IOException {
                    // 使用的是默认的编码表
                    // OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(
                    // "osw.txt"));
                    OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(
                            "osw.txt"), "UTF-8"); // GBK,UTF-8
                    // FileWriter osw = new FileWriter("osw.txt");
                    osw.write("中国");
                    osw.close();

                    InputStreamReader isr = new InputStreamReader(new FileInputStream(
                            "osw.txt"),"UTF-8");
                    char[] chs = new char[20];
                    int len = isr.read(chs);
                    String text = new String(chs,0,len);
                    System.out.println(text);
                }
            }

编码:字符串变成字节数组。


解码:字节数组变成字符串。

String-->byte[];  str.getBytes(charsetName);


byte[] -->String: new String(byte[],charsetName);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值