一、理论:

1、什么是输入输出?

输入输出的对象是数据,数据的存储区域是磁盘或者光盘等设备,我们知道还有一个存储数据的空间----内存,其中磁盘的速度比较慢,内存的速度比较快,把数据读入内存的动作称作输入,把数据从内存存入磁盘的动作称作输出。

2、流的分类按照流向:按照流向分为输入流和输出流

按照数据内容:字节流(能处理字节的流对象)、字符流(能处理字符的流对象)。

字符流的实质:字节流读取文字字节数据后,不直接操作而是先查指定的编码表,获取对应的文字,对文字进行操作,简单说,字符流=字节流+编码表。

备注:字符流出现的原因:面向字节的流不便于处理Unicode形式的存储信息,Unicode中的每个字符都使用了两个字节来标识,所以字节流处理不方便,所以出现了字符流,字符流的读入和写出操作是基于量子界的Unicode码元的。

关于Unicode推荐我的另一篇博文:ASCII到Unicode到UTF-8http://www.cnblogs.com/heisehenbai/p/7704827.html

3、常用基类;

字节流常用基类:

  • InputStream
  • OutputStream

字符流常用基类:

  • Reader
  • Writer

什么时候使用字符流:当需要操作字符的时候。

二、示例:

1、FileWriter的使用:

  • 创建相应的流----需要指定操作的路径,要操作什么文件new FileWriter(String fileName)(使用这个方法创建流,若是所指定的目录下没有该文件,则会创建,若是已存在,则会覆盖);
  • 对文件进行写入操作(调用write方法);
  • 调用flush方法,把写入缓冲区的内容冲刷到文件中(调用write(String content)方法写入的时候其实是把内容写入到了缓冲区中,磁盘中的文件事实上并不存在该内容)。
  • 关闭流(调用colose方法----事实上调用colose方法会自动对缓冲区进行冲刷,把缓冲区的内容写入文本)
  • 调用flush方法和调用colose方法的区别:调用flush方法之后还可以继续写入,而colose之后无法继续写入,反而会抛出IO异常。
        FileWriter fileWriter = null;
try {
fileWriter = new FileWriter("test.txt");
fileWriter.write("eke test");
fileWriter.flush();
} catch (IOException e) {
System.err.println(e.getMessage());
throw new RuntimeException("写入文件失败!"); } finally {
if (fileWriter != null) {
try {
fileWriter.close();
} catch (Exception e) {
System.err.println(e.getMessage());
throw new RuntimeException("关闭文件流失败");
} }
}

  运行结果将在项目的运行目录下创建文本文件test.txt,并且在文件中写入文本:eke test.

代码解析:先创建一个FileWriter,这个类主要用来创建字符流,对文件进行操作。在IO操作当中我们经常会遇上IOException异常,因此我们需要捕获异常。另外,创建一个流进行对文件操作调用了操作系统的资源,在使用完毕之后需要对有限的操作系统资源进行释放,否则会导致系统资源被耗尽。所以在finally中需要调用close方法,同时,clos方法也是可能产生异常的,因此要进行捕获,而判断fileWriter不能为null的原因是fileWriter在创建的时候就有可能失败(可能出现找不到相应的路径,例如指定不存在的磁盘)。

注意:上面第一步有提到过,我们使用new FileWriter(String fileName)创建流会覆盖原本存在的文件,所以如果是要对已存在的文件进行续写操作,就需要使用重载的构造函数new FileWriter(String fileName,boolean append)来创建写入流。

2、FileWriter的使用:

  • 创建相应的流----需要指定操作的路径,要操作什么文件newWriter(String fileName)(使用这个方法创建流,若是所指定的目录下没有该文件,则会创建,若是已存在,则会覆盖);
  • 对文件进行读取操作(调用read方法,这个方法是返回一个int值,该值表示的是Unicode的码元----0~65535之间的整数);
      注意:因为返回的是码元,所以如果要打印出来成字符,需要强制转换成char类型的再输出,而在使用FileWriter的write方法的时候可以直接使用返回的码元进行写入。
  • 调用flush方法,把写入缓冲区的内容冲刷到文件中(调用write(String content)方法写入的时候其实是把内容写入到了缓冲区中,磁盘中的文件事实上并不存在该内容)。
  • 关闭流(调用colose方法----事实上调用colose方法会自动对缓冲区进行冲刷,把缓冲区的内容写入文本)
  • 调用flush方法和调用colose方法的区别:调用flush方法之后还可以继续写入,而colose之后无法继续写入,反而会抛出IO异常。
        FileReader fileReader = null;
try {
fileReader = new FileReader("test.txt"); int charUnit=0;
while((charUnit=fileReader.read())!=-1){
System.out.print((char)charUnit);
} } catch (IOException e) {
System.err.println(e.getMessage());
throw new RuntimeException("写入文件失败!"); } finally {
if (fileReader != null) {
try {
fileReader.close();
} catch (Exception e) {
System.err.println(e.getMessage());
throw new RuntimeException("关闭文件流失败");
} }
}

  以下是输出成果:

Disconnected from the target VM, address: '127.0.0.1:36988', transport: 'socket'
eke test
Process finished with exit code 0

  

3、改进:

使用char数组来一次性读取多个字符:

            char[] contentArray = new char[1024];

            int charUnit = 0;
while ((charUnit = fileReader.read(contentArray)) != -1) {
System.out.println(new String(contentArray,0,charUnit));
}

  如上代码中的read方法使用了参数char[] contentArray;该方法返回的是读取的个数,并且把读取到的字符插入到contentArray数组中。

4、FileWriter与FileReader的联合使用----复制

FileReader fileReader = null;
FileWriter fileWriter = null; try {
fileReader = new FileReader("借我----木心.txt");
fileWriter = new FileWriter("test.txt"); char[] contentArray = new char[1024]; int charUnit = 0;
while ((charUnit = fileReader.read(contentArray)) != -1) {
System.out.println(new String(contentArray, 0, charUnit));
fileWriter.write(contentArray, 0, charUnit);
}
} catch (IOException e) {
System.err.println(e.getMessage());
throw new RuntimeException("写入文件失败!"); } finally {
if (fileReader != null) {
try {
fileReader.close();
} catch (Exception e) {
System.err.println(e.getMessage());
throw new RuntimeException("关闭文件流失败");
}
} if (fileWriter != null) {
try {
fileWriter.close();
} catch (Exception e) {
System.err.println(e.getMessage());
throw new RuntimeException("关闭文件流失败");
}
}
} FileReader reader = null; try {
reader = new FileReader("test.txt");
char[] contentArray = new char[1024]; int charUnit = 0;
while ((charUnit = reader.read(contentArray)) != -1) {
System.out.println(new String(contentArray, 0, charUnit));
} } catch (IOException e) {
throw new RuntimeException("读取流出现异常"); } finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
throw new RuntimeException("关闭流出现异常");
}
}
}

  结果将打印出我很喜欢的一首诗:

Connected to the target VM, address: '127.0.0.1:40996', transport: 'socket'
借我
----木心 借我一个暮年,
借我碎片,
借我瞻前与顾后,
借我执拗如少年。
借我后天长成的先天,
借我变如不曾改变。
借我素淡的世故和明白的愚,
借我可预知的脸。
借我悲怆的磊落,
借我温软的鲁莽和玩笑的庄严。
借我最初与最终的不敢,
借我不言而喻的不见。
借我一场秋啊,可你说这已是冬天。 Disconnected from the target VM, address: '127.0.0.1:40996', transport: 'socket'

  

Java-IO流之输入输出流基础示例的更多相关文章

  1. Java Io 流(输入输出流)

    IO流,也就是输入和输出流,可分为字节流和字符流. 1. 字节流 (1). InputStream 输入流,用于读取文件 输入流常用API: inputStream.read()  读取一个字节 in ...

  2. Java中IO流,输入输出流概述与总结

    总结的很粗糙,以后时间富裕了好好修改一下. 1:Java语言定义了许多类专门负责各种方式的输入或者输出,这些类都被放在java.io包中.其中, 所有输入流类都是抽象类InputStream(字节输入 ...

  3. Java自学第10期——File类与IO流(输入输出流、处理流、转换流、缓冲流、Properties集合、打印流)

    1.IO简介 IO(输入输出)通过java.io包下的类和接口来支持,包下包括输入.输出两种IO流,每种输入输出流又可分为字符流和字节流两大类. 2.File类 File类是io包下与平台无关的文件和 ...

  4. IO流 - 字节输入输出流,文件的复制

    IO流 I:input - 输入(读取),eg:把硬盘的内容读取到内存 O: output - 输出(写入) eg:把内存中的东西写入硬盘保存 流:数字(字符/字节) 一般1个字符=2Byte,1By ...

  5. Java IO流总结(二)-示例

    1.使用文件操作的9大方法完成文件的判断 判断文件或目录是否存在 : exits() 返回值boolean型 * 判断是否是文件: isFile() boolean * 判断是否是目录: isDiec ...

  6. Java Io(数据输入输出流)

    Java Io 字节流中的DataInputStream 和 DataOutputStream,使用流更加方便,是流的一个扩展,更方便读取int, long,字符等类型数据. 事例代码如下: pack ...

  7. java IO流 之 字节输出流 OutputString()

    Java学习重点之一:OutputStream 字节输出流的使用 FileOutPutStream:子类,写出数据的通道 步骤: 1.获取目标文件 2.创建通道(如果原来没有目标文件,则会自动创建一个 ...

  8. java IO流 之 FIle类基础

    package IO; import java.io.File;import java.io.IOException; public class FileIO { /** * 构建及获取文件名信息 * ...

  9. IO流07_输入输出流总体系

    [javaIO体系中常用的流] [关于字符流和字节流的注意点] 通常,字节流比字符流功能更加强大,因为字节流可以处理所有的二进制文件. 但是字节流来处理字符,又需要将字节转换成字符,增加了编程复杂度. ...

随机推荐

  1. EffectiveC++ 第4章 设计与声明

    我根据自己的理解,对原文的精华部分进行了提炼,并在一些难以理解的地方加上了自己的"可能比较准确"的「翻译」. Chapter4 设计与声明 Designs and Declarat ...

  2. input全选和取消全选

    <!DOCTYPE html><html> <head> <meta charset="utf-8" /> <title> ...

  3. 使用Notepad++开发Java程序

    安装NppExec插件(已安装可跳过) 插件下载地址 我选择了最新的RC2 根据软件位数下载对应的版本,我直接下载了32位对应的dll 解压后里面有两个文件夹和一个dll文件 拷贝到Notepad++ ...

  4. L1-Day3

    L1-Day31.太阳从西边落下. [我的翻译]The sun falls in the west. [标准答案]The sun sets in the west. [对比分析]落下fall与set的 ...

  5. 激活函数——sigmoid函数(理解)

    0 - 定义 $Sigmoid$函数是一个在生物学中常见的S型函数,也称为$S$型生长曲线.在信息科学中,由于其单增以及反函数单增等性质,$Sigmoid$函数常被用作神经网络的阈值函数,将变量映射到 ...

  6. 设计模式五: 原型模式(Prototype)

    简介 原型模式是属于创建型模式的一种,是通过拷贝原型对象来创建新的对象. 万能的Java超类Object提供了clone()方法来实现对象的拷贝. 可以在以下场景中使用原型模式: 构造函数创建对象成本 ...

  7. 用户态与内核态 & 文件流与文件描述符 简介

    用户态和内核态 程序代码的依赖和调用关系如下图所示: Lib:标准ASCI C函数,几乎所有的平台都支持该库函数,因此依赖该库的程序可移植性好: System Function:系统调用函数,与系统内 ...

  8. 关于TabLayout与ViewPager在Fragment中嵌套Fragment使用或配合使用的思考

    注意: 因为继承的是Fragment,所以getSupportFragmentManager()与getFragmentManager()方法无法使用,这里需要用到getChildFragmentMa ...

  9. pm2,部署nodejs,使用方法及自己使用后总结的经验

    pm2是一个带有负载均衡功能的应用进程管理器,可以用它来管理你的node进程,并查看node进程的状态,当然也支持性能监控,进程守护等功能.他会确定重启开机之后,能够保证程序也能运行起来.目前还没有操 ...

  10. selenium之 webdriver与三大浏览器版本映射表(更新至v2.29)

    1.chrome浏览器 chromedriver版本 支持的Chrome版本 v2.29 v56-58 v2.28 v55-57 v2.27 v54-56 v2.26 v53-55 v2.25 v53 ...