Java中的 IO新手学习篇

转自:点击打开链接

   一、简介

   IO操作面临很多问题,信息量的巨大,网络的环境等等,因为IO不仅仅是对本地文件、目录的操作,有时对二进制流、还有一部分是网络方面的资源,所以多种原因直接造成IO操作无疑是耗时且复杂多变的。Java对IO的支持是个不断的演变过程,经过了很多的优化,直到JDK1.4以后,才趋于稳定,在JDK1.4中,加入了nio类,解决了很多性能问题,虽然我们有足够的理由不去了解关于Java IO以前的情况,但是为了学好现在的类,我们还是打算去研究下,通过掌握类的优化情况来彻底理解IO的机制!Java IO主要主要在java.io包下,分为四大块近80个类:

   1、基于字节操作的I/O接口:InputStream和OutputStream

   2、基于字符操作的I/O接口:Writer和Reader

   3、基于磁盘操作的I/O接口:File

   4、基于网络操作的I/O接口:Socket(不在java.io包下)

   影响IO性能的无非就是两大因素:数据的格式及存储的方式,前两类主要是数据格式方面的,后两个类是存储方式方面的:本地和网络。所以策划好这两个方面的活动,有助于我们合理使用IO。

   二、基于字节的I/O操作(InputStream和OutputStream)

   我们先来看看类图:

    

   图1

    

   图2

   二者类似,我只详细讲解InputStream类,OutputStream留给大家自己去学习。InputStream类是个抽象类,里面核心的方法就是read()、read(byte b[])、read(byte b[], int off, int len),这三个方法是用于读取数据的底层的方法,他们可以用来读取一下这些类型的数据:

   A. 字节数组

   B. String对象

   C. 文件

   D. 管道,从一端进入,从另一端输出

   E. 流

   F. internet资源

   每一种数据源都有相应的InputStream子类,因为InputStream是个处于顶层的类,用来处理各种数据源的类都继承了InputStream类,我们来看看这些类:

   ByteArrayInputStream:处理字节数组的类,允许将内存的缓冲区当做InputStream使用。

   StringBufferInputStream:将String转换成InputStream,内部实现用的是StringBuffer。

   FileInputStream:从文件中读取数据。

   PipedInputStream:用于从管道中读取数据。

   SequenceInputStream:将多个流对象转化成一个InputStream。

   FilterInputStream:装饰器类,为其它InputStream类提供功能。

   
做过关于IO操作的读者知道,我们很少单独使用哪个类来实现IO操作,平时都是几个类合起来使用,这其实体现了一种装饰器模式(详见:http://blog.csdn.net/zhangerqing)的思想,在后面的分析中我们会详细的分析。从上面的图1中我们可以看出,FilterInputStream虽说是Inputstream的子类,但它依然是BufferedInputStream、DataInputStream、LineNumberInputStream、PushbackInputStream类的父类,这四个类分别提供了最贴近我们程序员使用的方法,如:readInt() 、readInt()、readInt()等等。对于IO操作,不管是磁盘还是网络,最终都是对字节的操作,而我们平时写的程序都是字符形式的,所以在传输的过程中需要进行转换。在字符到字节的转换过程中,我们需要用到一个类:InputStreamReader。

三、基于字符的I/O操作(Writer和Reader)

       Writer和Reader操作的目的就是操作字符和不是字节,和InputStream和OutputStream配合增加IO效果。通过InputStreamReader和OutputStreamReader可以进行字节和字符的转换,设计Writer和Reader的目的是国际化,使IO操作支持16位的Unicode。我把它们单独的画出来,因为要是全画的话,太大了放不下,有兴趣的TX可以在rational rose中导入其带的JDK类图看看,很过瘾的!

四、基于磁盘的I/O操作(File)

五、基于网络的I/O操作(Socket)

六、NIO

四-六部分由于时间关系,还没有整理完,后续会补出来!

七、经典IO操作

   1、缓冲输入文件。

import java.io.BufferedReader; 
import java.io.FileReader; 
 
public class InputStreamTest { 

    public static String read(String filename) throws Exception { 
        BufferedReader br = new BufferedReader(new FileReader(filename)); 
        String s; 
        StringBuffer sb = new StringBuffer(); 
        while ((s = br.readLine()) != null) { 
            sb.append(s + "\n"); 
        } 
        br.close(); 
        return sb.toString(); 
    } 
 
    public static void main(String[] args) throws Exception { 
        System.out.println(read("src/InputStreamTest.java")); 
    } 
 } 
import java.io.BufferedReader;
import java.io.FileReader;
public class InputStreamTest {
    public static String read(String filename) throws Exception {
  	BufferedReader br = new BufferedReader(new FileReader(filename));
  	String s;
  	StringBuffer sb = new StringBuffer();
  	while ((s = br.readLine()) != null) {
   		sb.append(s + "\n");
  	}
  	br.close();
 	 return sb.toString();
    }
    public static void main(String[] args) throws Exception {
  	System.out.println(read("src/InputStreamTest.java"));
    }


   这段代码是从磁盘读入InputStreamTest.java文件,然后转换成字符串。输出就是将源文件原样输出。

   2、从内存中读取。

import java.io.StringReader; 
 
public class MemoryInput { 
 
    public static void main(String[] args) throws Exception { 
        StringReader in = new StringReader( 
                InputStreamTest.read("src/MemoryInput.java")); 
        int c; 
        while ((c = in.read()) != -1) 
            System.out.println((char) c); 
    } 
 
} 
import java.io.StringReader;
   public class MemoryInput {
    	public static void main(String[] args) throws Exception {
  		StringReader in = new StringReader(InputStreamTest.read("src/MemoryInput.java"));
  		int c;
 		while ((c = in.read()) != -1)
   		     System.out.println((char) c);
   	}
   }

   read返回的是int类型的数据,所以在输出语句中用char做了强类型转换。该程序将一个一个的输出字符。

   3、基本的文件输出。

import java.io.BufferedReader; 
import java.io.BufferedWriter; 
import java.io.FileWriter; 
import java.io.PrintWriter; 
import java.io.StringReader; 
 
public class BasicFileOutput { 
    static String file = "basie.out"; 
    public static void main(String[] args) throws Exception { 
        BufferedReader in = new BufferedReader(new StringReader(InputStreamTest.read("src/BasicFileOutput.java"))); 
        PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter( file))); 
        int lineCount = 1; 
        String s; 
        while ((s = in.readLine()) != null) { 
            out.println(lineCount++ + ": " + s); 
        } 
        out.close(); 
        System.out.println(InputStreamTest.read(file)); 
    } 
} 

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.io.StringReader;
public class BasicFileOutput {
	static String file = "basie.out";
    	public static void main(String[] args) throws Exception {
  	     BufferedReader in = new BufferedReader(new StringReader(InputStreamTest.read("src/BasicFileOutput.java")));
  	     PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(file)));
  	     int lineCount = 1;
  	     String s;
  	     while ((s = in.readLine()) != null) {
   		  out.println(lineCount++ + ": " + s);
  	     }
  	     out.close();
  	     System.out.println(InputStreamTest.read(file));
 	}
}

   输出:

   1: import java.io.BufferedReader;

   2: import java.io.BufferedWriter;

   3: import java.io.FileWriter;

   …

    4、RandomAccessFile

   RandomAccessFile被我们称为”自我独立的类”,因为它独立于我们前面说的IO类,与InputStream和OutputStream没什么关系,除了实现了DataOutput, DataInput两个接口外。所有方法都是重新编写,而且很多都是native方法,我们来看个例子,了解下这个类:

   

    5、管道流

八、标准I/O

   就是我们最原始的使用的从控制台输入或者输出的那些类和方法,如System.in、System.out等。 

public class StandardIO {  
    public static void main(String[] args) throws IOException { 
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); 
        String s; 
        while ((s = in.readLine()) != null && s.length() != 0) 
            System.out.println(s); 
    } 
} 
public class StandardIO {
    public static void main(String[] args) throws IOException {
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    String s;
    while ((s = in.readLine()) != null && s.length() != 0)
        System.out.println(s);
    }
}

    System.in返回的是未经包装的InputStream对象,所以需要进行装饰,经InputStreamReader转换为Reader对象,放入BufferedReader的构造方法中。除此之外,System.out和System.err都是直接的PriintStream对象,可直接使用。我们也可以使用java.util包下的Scanner类来代替上述程序:

   

public class StandardIO { 
 
    public static void main(String[] args) throws IOException { 
        Scanner in = new Scanner(System.in); 
        String s; 
        while((s = in.next()) != null && s.length() != 0){ 
            System.out.println(s); 
        } 
    } 
} 
public class StandardIO {
    public static void main(String[] args) throws IOException {
  	Scanner in = new Scanner(System.in);
  	String s;
  	while((s = in.next()) != null && s.length() != 0){
   		System.out.println(s);
  	}
    }
}

public class StandardIO { 
 
    public static void main(String[] args) throws IOException { 
        Scanner in = new Scanner(System.in); 
        String s; 
        while((s = in.next()) != null && s.length() != 0){ 
            System.out.println(s); 
        } 
    } 
} 
public class StandardIO {
    public static void main(String[] args) throws IOException {
  	Scanner in = new Scanner(System.in);
  	String s;
  	while((s = in.next()) != null && s.length() != 0){
   		System.out.println(s);
  	}
    }
}

九、性能分析及总结

   1、一个文件读写工具类。

import java.io.BufferedReader; 
import java.io.File; 
import java.io.FileReader; 
import java.io.IOException; 
import java.io.PrintWriter; 
import java.util.ArrayList; 
import java.util.Arrays; 
 
/**
 * 一个非常实用的文件操作类 . 2012-12-19
 * 
 * @author Bruce Eckel , edited by erqing
 * 
 */ 
public class TextFile extends ArrayList<String> { 
    private static final long serialVersionUID = -1942855619975438512L; 
    // Read a file as a String  
    public static String read(String filename) { 
        StringBuilder sb = new StringBuilder(); 
        try { 
            BufferedReader in = new BufferedReader(new FileReader(new File(filename).getAbsoluteFile())); 
            String s; 
            try { 
                while ((s = in.readLine()) != null) { 
                    sb.append(s); 
                    sb.append("\n"); 
                } 
            } finally { 
                in.close(); 
            } 
 
        } catch (IOException e) { 
            throw new RuntimeException(e); 
        } 
       	    return sb.toString(); 
    } 
 
    // Write a single file in one method call  
    public static void write(String fileName, String text) { 
        try { 
            PrintWriter out = new PrintWriter( 
                    new File(fileName).getAbsoluteFile()); 
            try { 
                out.print(text); 
            } finally { 
                out.close(); 
            } 
        } catch (IOException e) { 
            throw new RuntimeException(e); 
        } 
    } 
 
    // Read a file,spilt by any regular expression  
    public TextFile(String fileName, String splitter) { 
        super(Arrays.asList(read(fileName).split(splitter))); 
        if (get(0).equals("")) 
            remove(0); 
    } 
 
    // Normally read by lines  
    public TextFile(String fileName) { 
        this(fileName, "\n"); 
    } 
 
    public void write(String fileName) { 
        try { 
            PrintWriter out = new PrintWriter( 
                    new File(fileName).getAbsoluteFile()); 
            try { 
                for (String item : this) 
                    out.println(item); 
            } finally { 
                out.close(); 
            } 
 
        } catch (IOException e) { 
            throw new RuntimeException(e); 
        } 
 
    } 
 
    // test,I have generated a file named data.d at the root  
    public static void main(String[] args) { 
        /* read() test */ 
        System.out.println(read("data.d")); // testing is OK!  
 
        /* write() test */ 
        write("out.d", "helloworld\negg"); // testing is OK!  
 
        /* constractor test */ 
        TextFile tf = new TextFile("data.d"); // testing is OK!   
    } 
} 

    2、读取二进制文件。

import java.io.BufferedInputStream; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.IOException; 
 
/**
* to read the binary file
* 
* @author erqing
* 
*/ 
public class BinaryFile { 
 
    /* the parametre is a file */ 
    public static byte[] read(File file) throws IOException { 
        BufferedInputStream bf = new BufferedInputStream(new FileInputStream(file)); 
        try { 
            byte[] data = new byte[bf.available()]; 
            bf.read(data); 
            return data; 
        } finally { 
            bf.close(); 
        } 
    } 
 
    /* the param is the path of a file */ 
    public static byte[] read(String file) throws IOException { 
        return read(new File(file).getAbsoluteFile()); 
    } 
} 





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大生群体。无论你是计算机相关专业的生,还是对其他领域编程感兴趣的生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程,具备跨平台开发能力的大生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值