Java基础-IO流

  本章章节目录:

    1、Java File文件类介绍;

    2、Java常用的IO介绍及代码实例;

Java File文件类介绍:

   Java File类的功能非常强大,利用Java基本上可以对文件进行所有的操作。本文将对Java File文件操作类进行详细地分析,并将File类中的常用方法进行简单介绍,有需要的Java开发者可以看一下。

 File 目录列表器:

      File假如是一个Directory,可以通过list()方法得到这个目录下所有的文件和目录的名称数组,list()方法,一种是没有参数,一种是实现FilenameFilter接口的参数,例如要获得一个指定目录下的所有的java文件,就要使用第二种带参数的list()方法

 第一种:

   利用递归列出全部文件:

 public class FileDemo {
    public static void main(String[] args){
        File f =new File("e:\\java");
        showDir(f);
    }
    public static void showDir(File dir){
        System.out.println(dir);
        File[] files =dir.listFiles();
        for(File file:files){
            if(file.isDirectory())
                showDir(file);
            else 
                System.out.println(file);
        }
    }
}

 第二种:

  通过 FilenameFilter接口,能够过滤得到指定类型的文件或者目录,其中必须重写accept(File file,String path)方法。

public class FileList {

	public static void main(String[] args) {

		try {

			File path = new File("C:\\Users\\Tony\\Documents\\JVM深入分析");

			String[] list = path.list(new DirFilter(".doc"));

			for (int i = 0; i < list.length; i++)

				System.out.println(list[i]);

		} catch (Exception e) {

			e.printStackTrace();

		}
	}

}

class DirFilter implements FilenameFilter {

	String afn;

	DirFilter(String afn) {

		this.afn = afn;

	}

	@Override
	public boolean accept(java.io.File dir, String name) {
		//System.out.println(dir);
		//System.out.println(name);
		String f = new File(name).getName();
		return f.indexOf(afn) != -1;
	}

}

   目录的创建与检查:

       File 类并不仅仅是对现有目录路径、文件或者文件组的一个表示。亦可用一个 File 对象新建一个目录,甚至创建一个完整的目录路径——假如它尚不存在的话。亦可用它了解文件的属性(长度、上一次修改日期、读/写属性等),检查一个File 对象到底代表一个文件还是一个目录,以及删除一个文件等等。

    可以通过如下方法进行操作:

    创建方法

        1.boolean createNewFile() 不存在返回true 存在返回false

        2.boolean mkdir() 创建目录

        3.boolean mkdirs() 创建多级目录

    删除方法

        1.boolean delete()

        2.boolean deleteOnExit() 文件使用完成后删除

          public class FileDemo2 {
                public static void main(String[] args){
                    File f =new File("d:\\1.txt");
                    try {
                        System.out.println(f.createNewFile());//当文件存在时返回false
                        System.out.println(f.delete());//当文件不存在时返回false
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }

   判断方法

        1.boolean canExecute()判断文件是否可执行

        2.boolean canRead()判断文件是否可读

        3.boolean canWrite() 判断文件是否可写

        4.boolean exists() 判断文件是否存在

        5.boolean isDirectory()

        6.boolean isFile()

        7.boolean isHidden()

        8.boolean isAbsolute()判断是否是绝对路径 文件不存在也能判断

   获取方法

        1.String getName()

        2.String getPath()

        3.String getAbsolutePath()

        4.String getParent()//如果没有父目录返回null

        5.long lastModified()//获取最后一次修改的时间

        6.long length()

        7.boolean renameTo(File f)

        8.File[] liseRoots()//获取机器盘符

        9.String[] list()

        10.String[] list(FilenameFilter filter)

 案例: 

    找出d盘下所有的 .java 文件,拷贝至 c:\jad 目录下,并将所有文件的类型由.java 修改为.jad 

  public class FileList {
	public static void main(String[] args) {
		try {

			File path = new File("C:\\Users\\Tony\\Documents\\JVM深入分析");
			moveFile(path);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static void moveFile(File path) {
		File[] files = path.listFiles(new FilenameFilter() {
			@Override
			public boolean accept(File dir, String name) {
				String f = new File(name).getName();
				return f.indexOf(".java") != -1;
			}
		});
		for (File file : files) {
			if (file.isDirectory()) {
				moveFile(file);
			} else {

				String string = file.getPath();
				String str2 = file.getAbsolutePath();
				System.out.println(string + " _" + str2);
				file.renameTo(new File(string+ file.getName().substring(0,
								file.getName().lastIndexOf('.')) + ".jad"));
			}
		}
	}
}


IO流基本概念:

  IO流用来处理设备之间的数据传输 ,Java对数据的操作是通过流的方式,Java用于操作流的对象都是在IO包上

  流按操作数据分为两种:字节流和字符流 ,字节流的抽象基类:InputStream,OutputStream

  流按流向分为:输入流,输出流。字符流的抽象基类:Reader,Writer

  注:由这4个类派生出来的子类名称都是以其父类名作为子类名的后缀。

  如:InputStream的子类:FileInputStream  如:Reader的子类FileReader

  Java文件流采用的是装饰设计模式,装饰类是对某基类的封装,装饰类的底层是靠基类的功能实现的,所以装饰类往往需要基类作为构造函数的参数。

 Java语言的I/O库提供了四大等级结构:InputStream,OutputStream,Reader,Writer四个系列的类。

 InputStream和OutputStream处理8位字节流数据, Reader和Writer处理16位的字符流数据。

 InputStream和Reader处理输入, OutputStream和Writer处理输出,

  所以OutputStream,Reader,Writer这三类的装饰模式跟前面详细介绍的InputStream装饰模式大同小异,大家可以看书中其它部分对这三类的详细描述或者从网上也能找到有关资料。为了方便比较这几种类型,顺便附上Java语言的I/O层次结构图:

   下面的图表示:以InputStream和OutputStream形成的层次关系:

     blob.png 

   下面的图表示:以Reader和Writer形成的层次关系

        blob.png

    下面展示流之间的读取写入及字节流与字符流转换流程图。

     blob.png

常用JavaIO流分析:

IO流: FileInputStream 与 FileOutputStream

   FileInputStream 用于读取本地文件中的字节数据,继承自InputStream类

   FileOutputStream用于将字节数据写出到文件。继承自OutputStream类

/**
 * 通过 FileInputStream与FileOutputStream进行文件的复制
 * @author Tony
 *
 */
public class FileDemo1 {
	public static void main(String[] args) throws IOException {
		FileInputStream input=null;
		FileOutputStream out=null;
		try {
			input=new FileInputStream(new File("D:\\VieMallLogo.png"));
			out=new FileOutputStream(new File("D:\\VieMallLogo1.png"));
			byte[] flush=new byte[1024];
			int len=0;
			while ((len=input.read(flush))!=-1) {
				out.write(flush, 0, len);
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(input!=null){
				input.close();
			}
			if(out!=null){
				out.close();
			}
		}
		
	}

}

IO流:FileReader和FileWriter

   FileReader 用于以字符为单位读取文本文件,继承InputStreamReader。

   FileWriter类用于将字符数据写出到文本文件中继承OutputStreamWriter。

public class FileDemo2 {
      public static void main(String[] args) throws IOException {
           FileWriter fw = null;
           try {
                 fw = new FileWriter("D:\\FileWriterTest.txt");
                 // 调用write 方法,将字符串写入到流中
                 fw.write("alex test23");
                 // 刷新流对象中的缓冲中的数据
                 fw.flush();
           } catch (Exception e) {
           } finally {
                 try {
                      if (fw != null) {
                            // 关闭流资源,但是关闭之前会刷新一次内部的缓冲中的数据
                            fw.close();
                      }
                 } catch (IOException e) {
                      e.printStackTrace();
                 }
           }
           try {
                 FileReader fr=new FileReader("D:\\FileWriterTest.txt");  
                 char[] buf=new char[1024];  
                 int num=0;  
                 while((num=fr.read(buf))!=-1){
                      System.out.println(new String(buf,0,num)); 
                 }
                 fr.close();
           } catch (Exception e) {
           }
      }
 
}

 注:

    1.在使用FileReader 对象进行文件输入操作的时,JVM先读取本地文本文,然后将其格式转化为Unicode编码格式进行操作。再用FileWriter进行文本文件输出时则把Unicode编码格式再转换成本地(本地主机上)的编码格式(如ASCII或者GBK等)。

    2.FileReader与FileWriter两个类和FileInputStream和FileOutputStream两个类的操作方法基本相同,只不过前者基于字符,后者基于字节(byte),若操作的文件不是文本文件,则建议使用FileInputStream和FileOutputStream进行文件的输入输出。

常用IO流类:BufferedReader和BufferedWriter

    BufferedReader类用于缓冲读取字符,将字节流封装成BufferedReader对象,然后用readLine()逐行读入字符流,直到遇到换行符为止(相当于反复调用Reader类对象的read()方法读入多个字符)

    BufferedWriter提供字符的缓冲写出功能,将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。

实例:使用字符处理流实现文件复制:

实例:使用字符处理流实现文件复制:
 
public class FileDemo2 {
      public static void main(String[] args) throws IOException {
           try {
                 // 使用BufferedReader和BufferedWriter进行文件复制(操作的是字符,以行为单位读入字符)
                 FileReader fr = new FileReader("d:\\BugReport.txt");
                 BufferedReader br = new BufferedReader(fr);
                 FileWriter fw = new FileWriter("d:\\BugReport1.txt");
                 BufferedWriter bw = new BufferedWriter(fw);
 
                 String s = br.readLine();
                 while (null != s) {
                      bw.write(s);
                      // 由于BufferedReader的rendLIne()是不读入换行符的,所以写入换行时须用newLine()方法
                      bw.newLine();
                      // read=fis.read(b);
                      s = br.readLine();
                 }
 
                 br.close();
                 bw.close();
           } catch (IOException e) {
                 e.printStackTrace();
           }
      }
}

IO流:BufferedInputStream与BufferedOutputStream

     BufferedInputStream能为输入流提供缓冲区,能提高很多IO的速度。你可以一次读取一大块的数据,而不需要每次从网络或者磁盘中一次读取一个字节。特别是在访问大量磁盘数据时,缓冲通常会让IO快上许多。

为了给你的输入流加上缓冲,你需要把输入流包装到BufferedInputStream中,代码如下:

InputStream input = new BufferedInputStream(new FileInputStream("c:\\data\\input-file.txt"));

  很简单,不是吗?你可以给BufferedInputStream的构造函数传递一个值,设置内部使用的缓冲区设置大小(译者注:默认缓冲区大小8 * 1024B),就像这样:

InputStream input = new BufferedInputStream(new FileInputStream("c:\\data\\input-file.txt"), 8 * 1024);

  这个例子设置了8KB的缓冲区。最好把缓冲区大小设置成1024字节的整数倍,这样能更高效地利用内置缓冲区的磁盘。

除了能够为输入流提供缓冲区以外,其余方面BufferedInputStream基本与InputStream类似。

   BufferedOutputStream 与BufferedInputStream类似,BufferedOutputStream可以为输出流提供缓冲区。可以构造一个使用默认大小缓冲区的    BufferedOutputStream(译者注:默认缓冲区大小8 * 1024B),代码如下:

OutputStream output = new BufferedOutputStream(new FileOutputStream("c:\\data\\output-file.txt"));

 也可以手动设置缓冲区大小,代码如下:

 OutputStream output = new BufferedOutputStream(new FileOutputStream("c:\\data\\output-file.txt"), 8 * 1024);

   为了更好地使用内置缓冲区的磁盘,同样建议把缓冲区大小设置成1024的整数倍。

   除了能够为输出流提供缓冲区以外,其余方面BufferedOutputStream基本与OutputStream类似。唯一不同的时,你需要手动flush()方法确保写入到此输出流的数据真正写入到磁盘或者网络中。

字节流文件拷贝+缓冲流 ,提高性能、缓冲流(节点流)
public class FileDemo2 {
      public static void main(String[] args) throws IOException {
           try {
                 
                 //1、建立联系 源(存在且为文件) +目的地(文件可以不存在)  
                 File src=new File("d:\\BugReport.txt");
                 File dest =new File("d:\\BugReport1.txt");
                 if (!src.isFile()) { // 不是文件或者为null
                      System.out.println("只能拷贝文件");
                      throw new IOException("只能拷贝文件");
                 }
             
                 BufferedInputStream inputStream=new BufferedInputStream(new FileInputStream(src));
                 BufferedOutputStream outputStream=new BufferedOutputStream(new FileOutputStream(dest));
                  //3、文件拷贝   循环+读取+写出
                  byte[] flush =new byte[1024];
                 int len = 0;
                 // 读取
                 while (-1 != (len = inputStream.read(flush))) {
                      // 写出
                      outputStream.write(flush, 0, len);
                 }
                 outputStream.flush(); //强制刷出
                  //关闭流
                 outputStream.close();
            inputStream.close();
           } catch (IOException e) {
                 e.printStackTrace();
           }
      }
}

IO流:InpunStreamReader和InputStreamWriter

   转换流:编码与解码的问题 InputStreamReader 将字节流转换为字符流。是字节流通向字符流的桥梁。如果不指定字符集编码,该解码过程将使用平台默认的字符编码,

   OutputStreamWriter 将字节流转换为字符流。是字节流通向字符流的桥梁。如果不指定字符集编码,该解码过程将使用平台默认的字符编码,如:GBK。

public class FileDemo2 {
      public static void main(String[] args) throws IOException {
            /** 
         * 使用缓冲区 可以使用缓冲区对象的 read() 和  readLine()方法。 
         */  
        //读取字节流  
        InputStream in = new FileInputStream("D:\\BugReport.txt");//读取文件上的数据。  
        //将字节流向字符流的转换。  
        InputStreamReader isr = new InputStreamReader(in);//读取  
        //创建字符流缓冲区  
        BufferedReader bufr = new BufferedReader(isr);//缓冲  
        String line = null;  
        while((line = bufr.readLine())!=null){  
            System.out.println(line);  
        }  
        isr.close();  
      }  
}

public class FileDemo2 {
      public static void main(String[] args) throws IOException {
           OutputStream out = System.out;// 打印到控制台
           OutputStreamWriter osr = new OutputStreamWriter(out);// 输出
           String str = "你好吗?";// 你好吗?
           osr.write(str);
           osr.flush();
           osr.close();
      }
}

IO流: ByteArrayInputStream 与ByteArrayOutputStream 数组字节流;

    ByteArrayOutputStream类是在创建它的实例时,程序内部创建一个byte型别数组的缓冲区,然后利用ByteArrayOutputStream和          ByteArrayInputStream的实例向数组中写入或读出byte型数据。在网络传输中我们往往要传输很多变量,我们可以利用ByteArrayOutputStream把所有的变量收集到一起,然后一次性把数据发送出去。具体用法如下:

   ByteArrayOutputStream:    可以捕获内存缓冲区的数据,转换成字节数组。ByteArrayInputStream: 可以将字节数组转化为输入流

/**
 *1、文件  --程序->字节数组
 *1)、文件输入流     
 *        字节数组输出流
 *
 *
 * 2、字节数组  --程序->文件
 * 1)、字节数组输入流
 *         文件输出流
 * @author Administrator
 *
 */
public class ByteArrayDemo02 {
 
    /**
     * @param args
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {
        byte[] data =getBytesFromFile("e:/xp/test/1.jpg");
        toFileFromByteArray(data,"e:/xp/test/arr.jpg");
    }
    /**
     * 2、字节数组  --程序->文件
     */
    public static void toFileFromByteArray(byte[] src,String destPath) throws IOException{
        //创建源
        //目的地
        File dest=new File(destPath);
        //选择流
        //字节数组输入流
        InputStream is =new BufferedInputStream(new ByteArrayInputStream(src));        
        //文件输出流
        OutputStream os =new BufferedOutputStream(new FileOutputStream(dest));
 
        //操作 不断读取字节数组
        byte[] flush =new byte[1];
        int len =0;
        while(-1!=(len =is.read(flush))){
            //写出到文件中
            os.write(flush, 0, len);
        }
        os.flush();
 
        //释放资源
        os.close();
        is.close();
 
    } 
 
 
    /**
     * 1、文件  --程序->字节数组
     * @return
     * @throws IOException 
     */
    public static byte[] getBytesFromFile(String srcPath) throws IOException{
        //创建文件源
        File src =new File(srcPath);
        //创建字节数组目的地 
        byte[] dest =null;
        //选择流
        //文件输入流     
        InputStream is =new BufferedInputStream(new FileInputStream(src));
        //字节数组输出流 不能使用多态
        ByteArrayOutputStream bos =new ByteArrayOutputStream();
 
        //操作   不断读取文件 写出到字节数组流中
        byte[] flush =new byte[1024];
        int len =0;
        while(-1!=(len =is.read(flush))){
            //写出到字节数组流中
            bos.write(flush, 0, len);
        }
        bos.flush();
        //获取数据
        dest =bos.toByteArray();
 
        bos.close();
        is.close();        
        return dest;
    }
 
}

IO流: ObjectInputStream与ObjectOutputStream

       java.io.ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。

  java.io.ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。

//反序列化
    public static void read(String destPath) throws IOException, ClassNotFoundException{
        //创建源
        File src =new File(destPath);
        //选择流
        ObjectInputStream dis =new ObjectInputStream(
                    new BufferedInputStream(
                                new FileInputStream(src)
                            )
                );
 
        //操作 读取的顺序与写出一致   必须存在才能读取
        //不一致,数据存在问题
        Object obj =dis.readObject();
        if(obj instanceof Employee){
            Employee emp=(Employee)obj;
            System.out.println(emp.getName());
            System.out.println(emp.getSalary());
        }
 
        obj =dis.readObject();
        int[] arr=(int[])obj;
        System.out.println(Arrays.toString(arr));
        dis.close();
    }
 
    //序列化
    public static void seri(String destPath) throws IOException{
        Employee emp =new Employee("bjsxt",1000000);
        int[] arr ={1,2,3,45};
        //创建源
        File dest =new File(destPath);
        //选择流  ObjectOutputStream
        ObjectOutputStream dos =new ObjectOutputStream(
                    new BufferedOutputStream(
                                new FileOutputStream(dest)
                            )
                );
        //操作 写出的顺序 为读取准备
        dos.writeObject(emp);
        dos.writeObject(arr);
        //释放资源
        dos.close();
    }

IO管道流PipedOutputStream和PipedInputStream

     PipedInputStream类与PipedOutputStream类用于在应用程序中创建管道通信.一个PipedInputStream实例对象必须和一个PipedOutputStream实例对象进行连接而产生一个通信管道.PipedOutputStream可以向管道中写入数据,PipedIntputStream可以读取PipedOutputStream向管道中写入的数据.这两个类主要用来完成线程之间的通信.一个线程的PipedInputStream对象能够从另外一个线程的PipedOutputStream对象中读取数据.

[示例]:管道流
*/
import java.io.*;

class Demo            
{
  public static void main(String[] args)  throws Exception
  {
    PipedInputStream pin = new PipedInputStream();
    PipedOutputStream pout = new PipedOutputStream();
    pin.connect(pout);  //输入流与输出流连接
    
    ReadThread readTh   = new ReadThread(pin);
    WriteThread writeTh = new WriteThread(pout);
    new Thread(readTh).start();
    new Thread(writeTh).start();
  }
  
  public static void sop(Object obj) //打印
  {
    System.out.println(obj);
  }
}

class ReadThread implements Runnable
{
  private PipedInputStream pin;
  ReadThread(PipedInputStream pin)   //
  {
    this.pin=pin;
  }
  
  public void run() //由于必须要覆盖run方法,所以这里不能抛,只能try
  {
    try
    {
      sop("R:读取前没有数据,阻塞中...等待数据传过来再输出到控制台...");
      byte[] buf = new byte[1024];
      int len = pin.read(buf);  //read阻塞
      sop("R:读取数据成功,阻塞解除...");
      
      String s= new String(buf,0,len);
      sop(s);    //将读取的数据流用字符串以字符串打印出来
      pin.close();     
    }
    catch(Exception e)
    {
      throw new RuntimeException("R:管道读取流失败!");
    }   
  }
  
  public static void sop(Object obj) //打印
  {
    System.out.println(obj);
  }
}

class WriteThread implements Runnable
{
  private PipedOutputStream pout;
  WriteThread(PipedOutputStream pout)
  {
    this.pout=  pout;
  }
  
  public void run()
  {
    try
    {
      sop("W:开始将数据写入:但等个5秒让我们观察...");
      Thread.sleep(5000);  //释放cpu执行权5秒
      pout.write("W: writePiped 数据...".getBytes());  //管道输出流
      pout.close();
    }
    catch(Exception e)
    {
      throw new RuntimeException("W:WriteThread写入失败...");
    }
  }
  
  public static void sop(Object obj) //打印
  {
    System.out.println(obj);
  }
}

常用IO流类: PrintStream和PrintWriter

     PrintStream: PrintStream在OutputStream基础之上提供了增强的功能,即可以方便地输出各种类型的数据(而不仅限于byte型)的格式化表示形式。PrintStream的方法从不抛出IOEceptin

    PrintWriter:PrintWriter提供了PrintStream的所有打印方法,其方法也从不抛出IOException。

与PrintStream的区别:作为处理流使用时,PrintStream只能封装OutputStream类型的字节流,而PrintWriter既可以封装OutputStream类型的字节流,还能够封装Writer类型的字符输出流并增强其功能。

常用IO流类: DataInputStream和DataOutputStream

  DataInputStream和DataOutputStream二者分别实现了DataInput/DataOutput接口

  DataInputStream能以一种与机器无关(当前操作系统等)的方式,直接从地从字节输入流读取JAVA基本类型和String类型的数据,常用于网络传输等(网络传输数据要求与平台无关)常用方法包括:

  DataOutputStream则能够直接将JAVA基本类型和String类型数据写入到其他的字节输入流。

常用IO流类:SequenceInputStream 

     把多个 InputStream 合并为一个 InputStream . “序列输入流”类允许应用程序把几个输入流连续地合并起来,并且使它们像单个输入流一样出现。每个输入流依次被读取,直到到达该流的末尾。然后“序列输入流”类关闭这个流并自动地切换到下一个输入流。

  construct—

    SequenceInputStream(Enumeration) 创建一个新的序列输入流,并用指定的输入流的枚举值初始化它。

    SequenceInputStream(InputStream, InputStream) 创建一个新的序列输入流,初始化为首先 读输入流 s1, 然后读输入流 s2 。

总结:根据不同的场景或者数据来源,来选择自己需要那个IO类,

一、按数据来源(去向)分类:

  1 、是文件: FileInputStream, FileOutputStream, ( 字节流 )FileReader, FileWriter( 字符 )

  2 、是 byte[] : ByteArrayInputStream, ByteArrayOutputStream( 字节流 )

  3 、是 Char[]: CharArrayReader, CharArrayWriter( 字符流 )

  4 、是 String: StringBufferInputStream, StringBufferOuputStream ( 字节流 )StringReader, StringWriter( 字符流 )

   5 、网络数据流: InputStream, OutputStream,( 字节流 ) Reader, Writer( 字符流 )

二、按是否格式化输出分:

    1 、要格式化输出: PrintStream, PrintWriter

三、按是否要缓冲分:

    1 、要缓冲: BufferedInputStream, BufferedOutputStream,( 字节流 ) BufferedReader, BufferedWriter( 字符流 )

四、按数据格式分:

    1 、二进制格式(只要不能确定是纯文本的) : InputStream, OutputStream 及其所有带 Stream 结束的子类

    2 、纯文本格式(含纯英文与汉字或其他编码方式); Reader, Writer 及其所有带 Reader, Writer 的子类

五、按输入输出分:

    1 、输入: Reader, InputStream 类型的子类

    2 、输出: Writer, OutputStream 类型的子类

六、特殊需要:

   1 、从 Stream 到 Reader,Writer 的转换类: InputStreamReader, OutputStreamWriter

   2 、对象输入输出: ObjectInputStream, ObjectOutputStream

   3 、进程间通信: PipeInputStream, PipeOutputStream, PipeReader, PipeWriter

   4 、合并输入: SequenceInputStream

   5 、更特殊的需要: PushbackInputStream, PushbackReader, LineNumberInputStream, LineNumberReader

jdk1.4后的Java.nio.*包中引入了新的Java/IO类库,其目的在于提高速度,实际上,旧的IO包已经使用NIO重新实现过,以便提高性能,接下来我将进入新的Java的IO,学习BIO、NIO、AIO。

发表评论