`
hanwangkun
  • 浏览: 42097 次
  • 性别: 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有了更深入的认识。从而也映证了我的观点:通过给别人培训,可以大大加深你对这块知识的应用与理解,这对自学是非常有用的。

 

分享到:
评论

相关推荐

    Java NIO 网络编程初探

    Java NIO 网络编程初探 1. Java NIO Java 1.4 版本添加了一个新的IO API,称为NIO(New IO)。NIO拥有所有IO的功能,但是操作方法却完全不一样。NIO支持面向缓冲区的、基于通道的IO操作。能够更加高效的进行IO操作。...

    Java在线开放课程建设初探.zip

    Java在线开放课程建设初探,这是一个关于如何构建和优化Java教育平台的主题,旨在分享和探讨在互联网时代如何有效地提供高质量的编程教育资源。本课程的构建不仅涵盖了技术层面的实现,还包括了教学方法、课程设计...

    计算机软件开发中JAVA编程语言及其实际应用.pdf

    在金融服务行业中,Java为金融系统提供了一层安全保障,能够快速处理大量慢速IO请求,并且能够构建稳定且美观的用户交易界面。JavaSwing为Java提供了GUI工具包,使得能够开发出个性化的图形用户界面。这使得金融行业...

    Java萌新作业 - 酒店管理系统

    《Java酒店管理系统初探》 Java编程语言在软件开发领域占据着重要的地位,尤其在企业级应用中,其稳定性和可扩展性深受开发者喜爱。本项目“Java萌新作业 - 酒店管理系统”就是一个很好的实践平台,让我们一同探讨...

    Java-program-design-.rar_Java 8

    压缩包可能还涵盖了异常处理、类和对象、继承、接口、抽象类、访问修饰符、封装、构造器、集合框架(List、Set、Map)、IO流、反射、枚举、泛型等Java 8的关键特性。 每个章节都会通过实例和练习帮助学习者巩固所...

    java文件读写操作

    首先,Java提供了java.io包,其中包含了许多类用于处理输入输出,如File类、FileReader/Writer类、BufferedReader/Writer类等。这些类是进行文件操作的核心工具。 1. **文件读取**: - 使用`File`类创建一个代表...

    Netty初探:掌握高性能网络通信框架,提升Java网络编程技能

    BossGroup负责接收新的连接请求,一旦接收到新的连接,就会将连接分配给WorkerGroup,由WorkerGroup处理具体的IO读写和业务逻辑。 2. **Channel(通道)**:代表一个到另一端的连接,可以是TCP、UDP或任何其他协议。...

    grizzly初探

    传统的 Java IO 基于 BIO(Blocking IO),即阻塞式 I/O,当一个线程进行读写操作时,若数据未就绪,线程会被挂起,直到数据准备好。而 NIO 则不同,它采用多路复用器(Selector)来监控多个通道(Channels)的状态...

    Spring Boot 初探 | 第一篇:第一个Spring Boot程序(示例程序)

    **Spring Boot 初探:构建你的第一个应用** Spring Boot 是由 Pivotal 团队提供的全新框架,旨在简化 Spring 应用程序的初始搭建以及开发过程。它集成了大量常用的第三方库配置,如 JDBC、MongoDB、JPA、RabbitMQ、...

    Vertx-Web初探

    ### Vertx-Web初探 #### 一、项目概述与准备 ##### 1.1 基本项目结构 为了确保项目的顺利进行,首先需要创建一个Maven项目,并且按照以下结构组织: - 源代码包:`src/main/vertx` - 资源路径:`src/main/...

    Shopping.zip

    《简易超市管理系统——Java编程初探》 在Java编程领域,初学者往往通过编写实际的应用程序来提升自己的技能。这份名为"Shopping.zip"的压缩包文件,就是为Java初学者提供的一款简易超市管理系统的源代码实例。这个...

    java学习课件

    1. **创建Servlet所需类库**:创建Servlet时,需要导入`java.io.*`、`javax.servlet.*`和`javax.servlet.http.*`类库。这些类库提供了处理I/O操作、Servlet生命周期管理以及HTTP请求和响应的工具。 2. **Servlet的...

    socke编程初级教程

    import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; public class SimpleClient { public static void main(String[] args) throws Exception { Socket socket = new ...

    Bejixed:我做过的第一款游戏,使用基本的Java GUI库合并了声音文件和图像

    《Bejixed:Java GUI库实现的声音与图像融合游戏初探》 Bejixed是一款由开发者使用基础Java GUI库制作的个人首部游戏作品。它不仅展示了编程技术的应用,更体现了作者对游戏开发的热情和对Java图形用户界面的深入...

    Android 线程池、信号量、Looper、缓存初探

    Android系统中的`java.util.concurrent.ThreadPoolExecutor`是实现线程池的主要类。通过设置核心线程数、最大线程数和任务队列,我们可以根据需求调整线程池的行为。使用线程池可以避免频繁创建和销毁线程的开销,...

    PrimaAplicatieJava

    《Java编程初探:构建你的第一个应用程序》 Java是一种广泛使用的高级编程语言,以其跨平台、面向对象和安全性强的特点而备受青睐。"PrimaAplicatieJava"(意为“Java的第一个应用”)旨在帮助初学者理解Java编程的...

    RxAndroidDemo:rxjava初探

    【RxAndroidDemo:rxjava初探】 RxJava是一款在Java虚拟机上运行的反应式编程库,它将异步操作和事件驱动的编程模型引入到传统面向对象编程中。RxAndroid是RxJava的一个扩展,专门为Android平台进行了优化,使得...

    springboothello

    1. **初始化项目**:使用Spring Initializr(http://start.spring.io/)生成一个新的SpringBoot项目,选择Java语言和SpringBoot版本,添加web依赖。 2. **创建主程序类**:在生成的项目中,找到主程序类,通常命名...

    MyFirstApp

    《MyFirstApp——Java编程初探》 "MyFirstApp"是一个典型的初学者入门项目,主要使用Java语言进行开发。Java作为一种广泛应用于企业级应用、Android移动开发以及云计算等领域的编程语言,其语法清晰,面向对象特性...

Global site tag (gtag.js) - Google Analytics