`
hanwangkun
  • 浏览: 41445 次
  • 性别: Icon_minigender_1
  • 来自: 漳州
社区版块
存档分类
最新评论

Java IO 初探

    博客分类:
  • Java
阅读更多

       这段时间,在给公司的一批新员工培训Java  IO的过程中,重新对自己之前学的Java IO有了新的认识。

先从一段代码说起:如下:

 import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
public class SequenceStreamTest {
 /**
  * @throws Exception 
  * @功能  顺序输入流测试
//  */
 public static void main(String[] args) throws Exception 
 {
  FileInputStream fis_01 = new FileInputStream("D:\\Java IO\\测试数据\\error.txt");
        ByteArrayInputStream byis = new ByteArrayInputStream("德邦信息技术中心欢迎您".getBytes("GBK"));
  FileInputStream fis_02 = new FileInputStream("D:\\Java IO\\测试数据\\清查明细.txt");
  List arrayList = new ArrayList();
  arrayList.add(fis_01);
  arrayList.add(byis);
  arrayList.add(fis_02);
  Enumeration cocel = Collections.enumeration(arrayList); 
  SequenceInputStream seq = new SequenceInputStream(cocel);
  byte[] buf = new byte[1024];
//  int i= -1;
  int n=0;
  FileOutputStream fout = new FileOutputStream("D:\\Java IO\\测试数据\\seq.txt");
  while((seq.read(buf))>0)
  {
            fout.write(buf);
            fout.flush();
  }
  
        seq.close();
  fout.close();
        
 }
}

         这段代码执行完成之后,我发现并不是我想要的结果。我的预期结果是,哪个流先加进去,就在结果文件中先出现它的内容。但是最后的结果是,第二个流的内容,在第一个流的内容里面,而且第一个流读取的内容有问题,出现了一些重复的内容。这个问题我在给新员工培训时,没有搞明白是什么问题。后来,课下,我思考了下,其实比较容易理解的。是这样的,对于同一个字节数组,从多个流读取数据,对每一个流的最后一次读取,并不一定能够装满这个字节数组,而没有装满这个数组的那部分内容,就是上一次读取的内容,就会出现内容重复及不同流的内容相互交叉的情况。所以,重点是要修改以下代码段:

		int n=0;
		FileOutputStream fout = new FileOutputStream("D:\\Java IO\\测试数据\\seq.txt");
                             while((n=seq.read(buf))>0)
                             {
                                       fout.write(buf,0,n);
                                       fout.flush();
		}

     接下来,又遇到一个问题:那就是教程里面说PrintStream这个类,在设置其自动刷新缓冲区后,只要调用println()即可自动把数据写到数据汇中,反之,就是如果不设置自动刷新,那么,调用println()就不会自动把数据写到数据汇中,但是接下来这段代码却出现了一些奇怪的现象:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.math.BigDecimal;


public class PrintStreamTest {

	/**
	 * @throws Exception 
	 * @功能 PrintStream测试
	 */
	public static void main(String[] args) throws Exception 
	{
		FileOutputStream fout = new FileOutputStream("H:\\常春藤培训\\韩旺坤\\Java IO\\测试数据\\ps.txt");
		fout.write("hanwangkunxx".getBytes());
                                PrintStream ps = new PrintStream(fout,false);
                                ps.print("2012年常春藤培训正式开始!");
                                ps.println("德邦信息技术中心欢迎大家加入这个大家庭!");
                                ps.println("2012年国庆中秋连续放假8天!");
                                ps.close();        
	}
}

    这段代码,按上面教程的理解,那么应该是:在每次调用println()后,不应该会把数据写到数据汇中,但是实际结果是每次调用之后都会把结果写到数据汇当中,这也是在课堂上未解决的问题。后来,在课下,我查看了源码及网上有关资料,发现是因为这样的:上面那条规则只是对有缓冲区的流才适用的,而我们的FileOutputStream及PrintStream都是没有缓冲区的,所以对这条规则是不适用的,所以如果换成下面的代码就可以了:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.math.BigDecimal;


public class PrintStreamTest {

	/**
	 * @throws Exception 
	 * @功能 PrintStream测试
	 */
	public static void main(String[] args) throws Exception 
	{
	     FileOutputStream fout   = new FileOutputStream("D:\\Java IO\\测试数据\\ps.txt");
                     fout.write("hanwangkunxx".getBytes());
                     PrintStream ps = new PrintStream(new BufferedOutputStream(fout),true);
                     ps.print("2012年常春藤培训正式开始!");
                     ps.println("德邦信息技术中心欢迎大家加入这个大家庭!");
                     ps.println("2012年国庆中秋连续放假8天!");
                     ps.close();       
	}
}

         从这个问题,我突然又发现了,不是说输出流只有在调用flush()方法或close()才会把数据写到数据汇中吗?但是第二个例子,却不是这样的。我查看了OutputStream及FileOutputStream两个流的源代码,发现对于OutputStream类,它的flush()方法是个空的方法,不做任何方法,而FileOutputStream并没有重写OutputStream的flush()方法,所以他们调用的是同一个方法,也就是说对于FileOutputStream流类,有没有调用flush()

方法,它都会把立即把数据写到数据汇中,再仔细一看FileOutputStream的write()方法,发现其是调用底层写的DLL文件来进行数据写操作的。

         

         此时,我又想起之前的一个问题,就是有些流的:markSupported()方法返回true,而有些返回false。经过查看源码,发现不仅这个方法,reset()和mark()方法都是针对有缓冲区的流来说的,对于有缓冲区的流这些方法都是

可以用的,使用这些方法对相应的数据源进行重复读写操作。

        

        至此,通过培训的几个问题,我对Java  IO有了更深入的认识。从而也映证了我的观点:通过给别人培训,可以大大加深你对这块知识的应用与理解,这对自学是非常有用的。

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics