java学习-2

来源:互联网 发布:c语言输出hello world 编辑:程序博客网 时间:2024/04/29 20:50
I/O流的层次

  1.字节流:

  从InputStream和OutputStream派生出来的一系列类。这类流以字节(byte)为基本处理单位。
  ◇ InputStream、OutputStream
  ◇ FileInputStream、FileOutputStream
  ◇ PipedInputStream、PipedOutputStream
  ◇ ByteArrayInputStream、ByteArrayOutputStream
  ◇ FilterInputStream、FilterOutputStream
  ◇ DataInputStream、DataOutputStream
  ◇ BufferedInputStream、BufferedOutputStream

 2.字符流:

  从Reader和Writer派生出的一系列类,这类流以16位的Unicode码表示的字符为基本处理单位。
  ◇ Reader、Writer
  ◇ InputStreamReader、OutputStreamWriter
  ◇ FileReader、FileWriter
  ◇ CharArrayReader、CharArrayWriter
  ◇ PipedReader、PipedWriter
  ◇ FilterReader、FilterWriter
  ◇ BufferedReader、BufferedWriter
  ◇ StringReader、StringWriter

 3.对象流

  ◇ ObjectInputStream、ObjectOutputStream

 4.其它

  ◇ 文件处理:
  File、RandomAccessFile;

  ◇ 接口
  DataInput、DataOutput、ObjectInput、ObjectOutput;


InputStream 和OutputStream

 1.InputStream

  ◇ 从流中读取数据:
  int read( ); //读取一个字节,返回值为所读的字节
  int read( byte b[ ] );
//读取多个字节,放置到字节数组b中,通常
              //读取的字节数量为b的长度,返回值为实际
              //读取的字节的数量
  int read( byte b[ ], int off, int len );
//读取len个字节,放置
                       //到以下标off开始字节
                       //数组b中,返回值为实
                       //际读取的字节的数量
  int available( );   //返回值为流中尚未读取的字节的数量
  long skip( long n );
//读指针跳过n个字节不读,返回值为实际
             //跳过的字节数量


  ◇ 关闭流:
  close( ); //流操作完毕后必须关闭
  
  ◇ 使用输入流中的标记:
  void mark( int readlimit );
//记录当前读指针所在位置,readlimit
                 //表示读
指针读出readlimit个字节后
                //所标记的
指针位置才失效
  void reset( );     //把读指针重新指向用mark方法所记录的位置
  boolean markSupported( ); //当前的流是否支持读指针的记录功能

  有关每个方法的使用,详见java API。


 2.OutputStream

  ◇ 输出数据:
  void write( int b );   //往流中写一个字节b
  void write( byte b[ ] ); //往流中写一个字节数组b
  void write( byte b[ ], int off, int len );
//把字节数组b中从
              //下标off开始,长度为len的字节写入流中

  ◇ flush( )       //刷空输出流,并输出所有被缓存的字节
  由于某些流支持缓存功能,该方法将把缓存中所有内容强制输出到流中。

  ◇ 关闭流:
   close( );       //流操作完毕后必须关闭

I/O中的例外

  进行I/O操作时可能会产生I/O例外,属于非运行时例外,应该在程序中处理。如:FileNotFoundException, EOFException, IOException

 

文件处理

   I/O处理中,最常见的是对文件的操作,java.io包中有关文件处理的类有:File、FileInputStream、 FileOutputStream、RamdomAccessFile和FileDescriptor;接口有:FilenameFilter。

文件描述


  类File提供了一种与机器无关的方式来描述一个文件对象的属性。下面我们介绍类File中提供的各种方法。

 ◇ 文件或目录的生成

  public File(String path);
/*如果path是实际存在的路径,则该File对象
    /*表示的是目录;如果path是文件名,则该File对象表示的是文件。*/
  public File(String path,String name);//path是路径名,name是文件名
  public File(File dir,String name);//dir是路径名,name是文件名

 ◇ 文件名的处理

  String getName( ); //得到一个文件的名称(不包括路径)
  String getPath( ); //得到一个文件的路径名
  String getAbsolutePath( );//得到一个文件的绝对路径名
  String getParent( ); //得到一个文件的上一级目录名
  String renameTo(File newName);
//将当前文件名更名为给定文件的
                   完整路径

 ◇ 文件属性测试

  boolean exists( ); //测试当前File对象所指示的文件是否存在
  boolean canWrite( );//测试当前文件是否可写
  boolean canRead( );//测试当前文件是否可读
  boolean isFile( ); //测试当前文件是否是文件(不是目录)
  boolean isDirectory( );
//测试当前文件是否是目录

 ◇ 普通文件信息和工具

  long lastModified( );//得到文件最近一次修改的时间
  long length( ); //得到文件的长度,以字节为单位
  boolean delete( ); //删除当前文件

 ◇ 目录操作

  boolean mkdir( ); //根据当前对象生成一个由该对象指定的路径
  String list( );
//列出当前目录下的文件

 【例4-3】
  import java.io.*; //引入java.io包中所有的类
  public class FileFilterTest{
    public static void main(String args[]){
     File dir=new File("d://ex"); //用File 对象表示一个目录
     Filter filter=new Filter("java"); //生成一个名为java的过滤器
     System.out.println("list java files in directory "+dir);
     String files[]=dir.list(filter);
//列出目录dir下,文件后缀名
                      为java的所有文件
     for(int i=0;i<files.length;i++){
      File f=new File(dir,files[i]);
//为目录dir 下的文件或目录
                       创建一个File 对象
       if(f.isFile())
//如果该对象为后缀为java的文件,
                则打印文件名
        System.out.println("file "+f);
       else
        System.out.println("sub directory "+f );
//如果是目录
                            则打印目录名
     }
    }
   }
   class Filter implements FilenameFilter{
    String extent;
    Filter(String extent){
     this.extent=extent;
    }
    public boolean accept(File dir,String name){
     return name.endsWith("."+extent); //返回文件的后缀名
    }
   }

文件的顺序处理

  
类FileInputStream和FileOutputStream用来进行文件I/O处理,由它们所提供的方法可以打开本地主机上的文件,并进行顺序的读/写。例如,下列的语句段是顺序读取文件名为text的文件里的内容,并显示在控制台上面,直到文件结束为止。

  FileInputStream fis;
   try{
    fis = new FileInputStream( "text" );
   System.out.print( "content of text is : ");
     int b;
     while( (b=fis.read())!=-1 )
//顺序读取文件text里的内容并赋值
                    给整型变量b,直到文件结束为止。
     {              
       System.out.print( (char)b );
     }
   }catch( FileNotFoundException e ){
   System.out.println( e );
   }catch( IOException e ){
   System.out.println( e );
   }

 随机访问文件

   对于InputStream 和OutputStream 来说,它们的实例都是顺序访问流,也就是说,只能对文件进行顺序地读/写。随机访问文件则允许对文件内容进行随机读/写。在java中,类 RandomAccessFile 提供了随机访问文件的方法。类RandomAccessFile的声明为:
public class RandomAccessFile extends Object implements DataInput, DataOutput

  接口DataInput 中定义的方法主要包括从流中读取基本类型的数据、读取一行数据、或者读取指定长度的字节数。如:readBoolean( )、readInt( )、readLine( )、readFully( ) 等。

  接口DataOutput 中定义的方法主要是向流中写入基本类型的数据、或者写入一定长度的字节数组。如:writeChar( )、writeDouble( )、write( ) 等。下面详细介绍RandomAccessFile类中的方法。

 ◇ 构造方法:
  RandomAccessFile(String name,String mode);
//name是文件名,mode
          //是打开方式,例如"r"表示只读,"rw"表示可读写,"
  RandomAccessFile(File file,String mode); //file是文件对象

 ◇ 文件指针的操作
  long getFilePointer( );
//用于得到当前的文件指针
  void seek( long pos ); //用于移动文件指针到指定的位置
  int skipBytes( int n ); //使文件指针向前移动指定的n个字节

 过滤流

  过 滤流在读/写数据的同时可以对数据进行处理,它提供了同步机制,使得某一时刻只有一个线程可以访问一个I/O流,以防止多个线程同时对一个I/O流进行操 作所带来的意想不到的结果。类FilterInputStream和FilterOutputStream分别作为所有过滤输入流和输出流的父类

  过滤流类层次:

          java.lang.Object
                |
                +----java.io.InputStream
                          |
                          +----java.io.FilterInputStream



  为了使用一个过滤流,必须首先把过滤流连接到某个输入/出流上,通常通过在构造方法的参数中指定所要连接的输入/出流来实现。例如:

  FilterInputStream( InputStream in );
  FilterOutputStream( OutputStream out );

 几种常见的过滤流

  ◇ BufferedInputStream和BufferedOutputStream
    缓冲流,用于提高输入/输出处理的效率。

  ◇ DataInputStream 和 DataOutputStream
   不仅能读/写数据流,而且能读/写各种的java语言的基本类型,如:boolean,int,float等。

  ◇ LineNumberInputStream
   除了提供对输入处理的支持外,LineNumberInputStream可以记录当前的行号。

  ◇ PushbackInputStream
   提供了一个方法可以把刚读过的字节退回到输入流中,以便重新再读一遍。

  ◇ PrintStream
    打印流的作用是把Java语言的内构类型以其字符表示形式送到相应的输出流。


字符流的处理


  java中提供了处理以16位的Unicode码表示的字符流的类,即以Reader和Writer 为基类派生出的一系列类。

 Reader和Writer

    这两个类是抽象类,只是提供了一系列用于字符流处理的接口,不能生成这两个类的实例,只能通过使用由它们派生出来的子类对象来处理字符流。

 
1.Reader类是处理所有字符流输入类的父类。

  ◇ 读取字符
  public int read() throws IOException; //读取一个字符,返回值为读取的字符
  public int read(char cbuf[]) throws IOException; /*读取一系列字符到数组cbuf[]中,返回值为实际读取的字符的数量*/
  public abstract int read(char cbuf[],int off,int len) throws IOException;
  /*读取len个字符,从数组cbuf[]的下标off处开始存放,返回值为实际读取的字符数量,该方法必须由子类实现*/

  ◇ 标记流
  public boolean markSupported(); //判断当前流是否支持做标记
  public void mark(int readAheadLimit) throws IOException;
   //给当前流作标记,最多支持readAheadLimit个字符的回溯。
  public void reset() throws IOException; //将当前流重置到做标记处

  ◇ 关闭流
  public abstract void close() throws IOException;

 2. Writer类是处理所有字符流输出类的父类。

  ◇ 向输出流写入字符
  public void write(int c) throws IOException;

  //将整型值c的低16位写入输出流
  public void write(char cbuf[]) throws IOException;
  //将字符数组cbuf[]写入输出流
  public abstract void write(char cbuf[],int off,int len) throws IOException;
  //将字符数组cbuf[]中的从索引为off的位置处开始的len个字符写入输出流
  public void write(String str) throws IOException;
  //将字符串str中的字符写入输出流
  public void write(String str,int off,int len) throws IOException;
  //将字符串str 中从索引off开始处的len个字符写入输出流

  ◇ flush( )
  刷空输出流,并输出所有被缓存的字节。

  ◇ 关闭流
  public abstract void close() throws IOException;

InputStreamReader和OutputStreamWriter

  java.io包中用于处理字符流的最基本的类,用来在字节流和字符流之间作为中介。

   ◇ 生成流对象
  public InputStreamReader(InputStream in);

  /*in是字节流,而InputStreamReader是字符流,但是其来源是字节流in,
  因此InputStreamReader就可以把字节流in转换成字符流处理。/*


  public InputStreamReader(InputStream in,String enc) throws UnsupportedEncodingException;
  
/*enc是编码方式,就是从字节流到字符流进行转换时所采用的编码方式,
   例如 ISO8859-1,UTF-8,UTF-16等等*/

  public OutputStreamWriter(OutputStream out);
  /*out是字节流,而OutputStreamReader是字符流 */

  public OutputStreamWriter(OutputStream out,String enc) throws UnsupportedEncodingException; //enc是编码方式

  InputStreamReader和OutputStreamWriter的方法:

  ◇ 读入和写出字符
  基本同Reader和Writer。

  ◇ 获取当前编码方式
  public String getEncoding();

  ◇ 关闭流
  public void close() throws IOException;


BufferedReader和BufferedWriter

 ◇ 生成流对象

  public BufferedReader(Reader in); //使用缺省的缓冲区大小
  public BufferedReader(Reader in, int sz); //sz为缓冲区的大小
  public BufferedWriter(Writer out);
  public BufferedWriter(Writer out, int sz);

 ◇ 读入/写出字符

  除了Reader和Writer中提供的基本的读写方法外,增加对整行字符的处理。
  public String readLine() throws IOException; //读一行字符
  public void newLine() throws IOException;
//写一行字符

【例4-4】


  import java.io.*;
  public class NumberInput{
   public static void main(String args[]){
    try{
      InputStreamReader ir;
      BufferedReader in;
      ir=new InputStreamReader(System.in);
      //从键盘接收了一个字符串的输入,并创建了一个字符输入流的对象
      in=new BufferedReader(ir);
      String s=in.readLine();
      //从输入流in中读入一行,并将读取的值赋值给字符串变量s
      System.out.println("Input value is: "+s);

      int i = Integer.parseInt(s);//转换成int型
      i*=2;
      System.out.println("Input value changed after doubled: "+i);
    }catch(IOException e)
    {System.out.println(e);}
   }
  }

    运行结果

D:/>java NumberInput
123
Input value is 123
Input value changed after doubled: 246

  注意:在读取字符流时,如果不是来自于本地的,比如说来自于网络上某处的与本地编码方式不同的机器,那么我们在构造输入流时就不能简单地使用本地缺省的编码方式,否则读出的字符就不正确;为了正确地读出异种机上的字符,我们应该使用下述方式构造输入流对象:
  ir = new InputStreamReader(is, "8859_1");

  
采用ISO 8859_1编码方式,这是一种映射到ASCII码的编码方式,可以在不同平台之间正确转换字符。

 
原创粉丝点击