Java流概念:

Java把所有的有序数据都抽象成流模型,简化了输入输出,理解了流模型就理解了Java IO。可以把流想象成水流,里面的水滴有序的朝某一方向流动。水滴就是数据,且代表着最小的数据流动单位,在字节流中,水滴就是一字节(byte),在字符流中,水滴就是一字符(char)。

Java流的分类方法大致分为以下几种:

1、按流向划分,分为输入流、输出流

请注意,这里的流向是以程序的运行时内存为参照的。 
输入流类名中包含关键字InputStream或Reader,输出流类名中包含关键字OutputStream或Writer。

2、按操作的数据单元类型划分,分为字节流、字符流

字节流操作的数据单元是8位的字节(byte),字符流操作的是16位的字符。 
字节流类名中包含关键字InputStream或OutputStream,字符流类名中包含关键字Reader或Writer。 
请注意,系统输入输出(System.in与System.out)都为字节流。

3、按流的角色来划分,分为节点流与处理流

节点流是指程序可以向一个特定的节点读写数据,直接连接数据源; 
这个节点最常见的是文件,类名中包含关键字File;还可以是数组、管道、字符串,关键字分别为ByteArray/CharArray,Piped,String。

处理流并不直接连接数据源,它大多情况是对已存在的节点流进行包装,是一种典型的装饰器设计模式。使用处理流主要是为了更方便的执行输入输出工作,如PrintStream,输出功能很强大,推荐输出时都使用处理流包装。

注意:一个IO流可以即是输入流又是字节流又或是以其他方式分类的流类型,是不冲突的。比如FileInputStream,它既是输入流又是字节流还是文件节点流。

4、一些特别的的流类型

转换流,转换流只有字节流转换为字符流,因为字符流使用起来更方便,我们只会向更方便使用的方向转化。如:InputStreamReader与OutputStreamWriter。

缓冲流,有关键字Buffered,也是一种处理流,为其包装的流增加了缓存功能,提高了输入输出的效率,增加缓冲功能后需要使用flush()才能将缓冲区中内容写入到实际的物理节点。但是,在现在版本的Java中,只需记得关闭输出流(调用close()方法),就会自动执行输出流的flush()方法,可以保证将缓冲区中内容写入。

对象流,有关键字Object,主要用于将目标对象保存到磁盘中或允许在网络中直接传输对象时使用(对象序列化),具体可参看博客Java序列化与反序列化

推回输入流,有关键字PushBack,当程序调用推回输入流的unread()方法时,系统回把指定数组内容的内容推回到一个推回缓冲区中,在调用read()方法读入内容时,就先从推回缓冲区中读取,直到读完推回缓冲区中内容后才会从原输入流中读取。

必须要掌握的流用法实例: 
1、FileInputStream\FileOutputStream\FileReader\FileWriter(使用方法类似)

//文件字节输入流FileInputStream用法
public class TestFileIO1 {
public static void main(String[] args)throws IOException{
//此处路径可以使用相对路径与绝对路径
FileInputStream fileInputStream = new FileInputStream("D:\\Git\\TCCP\\IO\\src\\package1\\TestFileIO1.java");
//一个字节数组作为缓冲,意为每次读取1024个字节,提高效率
byte[] buffer = new byte[1024];
//记录读取的字节数
int hasRead = 0;
//调用read()方法,返回实际读取的字节数
while((hasRead = fileInputStream.read(buffer)) > 0){
System.out.print(new String(buffer, 0, hasRead));
}
//关闭流
fileInputStream.close();
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
//文件字符输入流FileReader用法
public class TestFileIO2 {
public static void main(String[] args)throws IOException{
FileReader fileReader = new FileReader("D:\\Git\\TCCP\\IO\\src\\package1\\TestFileIO2.java");
char[] buffer = new char[32];
int hasRead = 0;
while((hasRead = fileReader.read(buffer)) > 0){
System.out.print(new String(buffer, 0, hasRead));
}
fileReader.close();
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
//文件字节输入流FileInputStream与文件字节输出流FileOutputStream结合
public class TestFileIO3 {
public static void main(String[] args)throws IOException{
File result = new File("output.txt");
FileInputStream fileInputStream = new FileInputStream("D:\\Git\\TCCP\\IO\\src\\package1\\TestFileIO3.java");
FileOutputStream fileOutputStream = new FileOutputStream(result);
byte[] buffer = new byte[1024];
int hasRead = 0;
while((hasRead = fileInputStream.read(buffer)) > 0){
fileOutputStream.write(buffer, 0, hasRead);
}
System.out.println(result.getAbsolutePath());
fileInputStream.close();
fileOutputStream.close();
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
//文件字符输出流FileWriter用法
public class TestFileIO4 {
public static void main(String[] args)throws IOException{
File result = new File("output.txt");
FileWriter fileWriter = new FileWriter(result);
fileWriter.write("飞流直下三千尺,\r\n");
fileWriter.write("疑是银河落九天.\r\n");
fileWriter.close();
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

2、输出处理流PrintStream用法

public class TestFileIO5 {
public static void main(String[] args)throws IOException{
File result = new File("output.txt");
FileOutputStream fileOutputStream = new FileOutputStream(result);
//PrintStream处理流功能极其强大,所有字节输出流都应使用PrintStream包装
PrintStream printStream = new PrintStream(fileOutputStream);
printStream.println("床前明月光,");
fileOutputStream.close();
printStream.close();
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

3、转换流inputStreamReader与缓冲流BufferedReader用法

public class TestFileIO6 {
public static void main(String[] args)throws IOException{
//系统输入为System.in,默认为从键盘输入,是字节输入流InputStream类型
//使用转换流将InputStream转换为Reader字符输入流对象
InputStreamReader inputStreamReader = new InputStreamReader(System.in);
//将Reader包装为字符缓存处理流BufferedReader对象
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
//定义缓存行
String bufferString = null;
//使用BufferedReader特色readLine()方法逐行读取输入
while((bufferString = bufferedReader.readLine()) != null){
//直到输入exit,停止程序
if(bufferString.equals("exit")){
System.exit(0);
}
//控制台输出输入内容
System.out.println("输入内容为:" + bufferString);
}
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

4、推回输入流PushbackInputStream

//通过一个返回某个字符串之前的文件内容的demo,理解推回输入流的读取缓存机制
public class TestFileIO7 {
public static void main(String[] args)throws IOException{
//创建一个推回字节输入流对象,指定缓冲区为64
PushbackReader pushbackInputStream = new PushbackReader(new FileReader("D:\\Git\\TCCP\\IO\\src\\package1\\TestFileIO7.java"), 64);
char[] buffer = new char[32];
//记录上次读取的字符串
String lastContent = "";
int hasRead = 0;
while((hasRead = pushbackInputStream.read(buffer)) > 0){
//将读取的字符转换为字符串
String content = new String(buffer, 0, hasRead);
int targetIndex = 0;
//将上次读取的字符串和本次读取的字符串拼接
//查找拼接后的字符串是否包含"new PushbackReader"(文件为此段源代码),返回位置由targetIndex记录
if((targetIndex = (lastContent + content).indexOf("targetIndex")) > 0){
//将拼接后字符串转化成字符数组后推回缓冲区
String newContent = lastContent + content;
pushbackInputStream.unread(newContent.toCharArray());
//定义一个长度为targetIndex的char数组,如果新大小大于32,则需要重新定义
if(targetIndex > 32){
buffer = new char[targetIndex];
}
//再次读取targetIndex长度的内容,其实就是目标字符串之前的内容
pushbackInputStream.read(buffer, 0, targetIndex);
//输出结果
System.out.println(new String(buffer, 0, targetIndex));
//退出程序
System.exit(0);
}
}
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

5、重定向标准输入\输入 
Java的标准输入为System.in默认为键盘输入,标准输入为System.out默认为屏幕输出。可通过setInt(InputStream in)方法与setOut(PrintStream out)方法修改(在这里,连标准输出的字节输出流都被包装成了PrintStream,我们在编程时有什么理由不适用输出流呢?)。

public class TestFileIO8 {
public static void main(String[] args)throws IOException{
FileInputStream fileInputStream = new FileInputStream("input.txt");
//重定向默认输入
System.setIn(fileInputStream);
//一次性创建PrintStream输出流对象(先创建文件字节输出流对象,再包装)
PrintStream printStream = new PrintStream(new FileOutputStream("output.txt"));
//重定向默认输出
System.setOut(printStream);
//获取System.in(input.txt文件中)的输入
Scanner scanner = new Scanner(System.in);
while(scanner.hasNext()){
//下面这段标准输出会输出在Output.txt中
System.out.println("输入的内容为:" + scanner.next());
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

6、对象处理流ObjectInputStream\ObjectOutputStream 
对象要想保存在磁盘或在网络上传输,其实体类必须可序列化,它是将对象转化为字节序列,使其可以脱机运行。 
要想实现序列化,实体类必须实现java.io.serializable接口。

//创建一个可序列化的实体类
public class Person implements Serializable{ private String username;
private int age;
public Person(String username, int age){
this.username = username;
this.age = age;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class TestObjectIO {
public static void main(String[] args) throws Exception{
//ObjectOutputStream是一个处理流,必须建立在节点流上才能工作
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("output.txt"));
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("output.txt"));
objectOutputStream.writeObject(new Person("Leeon", 21));
Person person = (Person)objectInputStream.readObject();
System.out.println(person.getUsername() + person.getAge());
objectInputStream.close();
objectOutputStream.close();
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhangliangzi/article/details/51226652

面试题:JavaIO流分类详解与常用流用法实例的更多相关文章

  1. 详解 I/O流

    I/O流是用于处理设备之前信息传输的流,在我们今后的学习甚至是工作中,都是十分重要的. 在我们的日常生活中,也是很常见的,譬如:文件内容的合并.设备之键的文件传输,甚至是下载软件时的断点续传,都可以用 ...

  2. (转)dp动态规划分类详解

    dp动态规划分类详解 转自:http://blog.csdn.NET/cc_again/article/details/25866971 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间 ...

  3. android shape的使用详解以及常用效果(渐变色、分割线、边框、半透明阴影效果等)

    shape使用.渐变色.分割线.边框.半透明.半透明阴影效果. 首先简单了解一下shape中常见的属性.(详细介绍参看  api文档 ) 转载请注明:Rflyee_大飞: http://blog.cs ...

  4. mybatis 详解(三)------入门实例(基于注解)

    1.创建MySQL数据库:mybatisDemo和表:user 详情参考:mybatis 详解(二)------入门实例(基于XML) 一致 2.建立一个Java工程,并导入相应的jar包,具体目录如 ...

  5. webpack4配置详解之常用插件分享

    前言 继上一次webpack的基础配置分享之后,本次将分享一些工作中项目常用的配置插件.也会包含一些自己了解过觉得不错的插件,如有分析不到位的,欢迎纠错,嗯,这些东西文档都有,大佬可绕过. Wepac ...

  6. [转帖]Ipvsadm参数详解(常用命令)

    Ipvsadm参数详解(常用命令) 2013年11月29日 12:41:40 怀素1980 阅读数:15901   版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.cs ...

  7. 分区工具parted的详解及常用分区使用方法【转】

    来源:http://blog.51cto.com/zhangmingqian/1068779 分区工具parted的详解及常用分区使用方法 一.         parted的用途及说明 概括使用说明 ...

  8. Git 命令详解及常用命令

    Git 命令详解及常用命令 Git作为常用的版本控制工具,多了解一些命令,将能省去很多时间,下面这张图是比较好的一张,贴出了看一下: 关于git,首先需要了解几个名词,如下: 1 2 3 4 Work ...

  9. RMAN命令详解和常用汇总

    RMAN命令详解和常用汇总转摘汇集,日后使用本文链接:https://blog.csdn.net/EVISWANG/article/details/50448370http://blog.itpub. ...

随机推荐

  1. 【ES6】蛋疼

  2. python学习之面向对象(上)

    定义了一个Animal类,该类包括了构造函数,私有方法,公有方法,静态方法,属性的方问等 双下划线"__"组成了私有成员的定义约束,其它情况则为公有成员 #_metaclass_= ...

  3. phpcms V9二级目录下分页路径不正确问题的彻底解决方法

    在用phpcms V9做二次开发的时候,我们有时候会把一个栏目生成到根目录下,而且这个栏目又有子栏目,我们生成静态的时候分页会出现问题,就是分页的路径的地址错误.有一种解决方法就是,把这个栏目生成动态 ...

  4. 转载的,讲解java.util的集合类

    本文是转载的 http://www.ibm.com/developerworks/cn/java/j-lo-set-operation/index.html#ibm-pcon 在实际的项目开发中会有很 ...

  5. tensorflow中常用激活函数和损失函数

    激活函数 各激活函数曲线对比 常用激活函数: tf.sigmoid() tf.tanh() tf.nn.relu() tf.nn.softplus() tf.nn.softmax() tf.nn.dr ...

  6. html页面中如何设置当光标移到一个固定区域时其形状变成手型,移出时恢复

    在除了IE6的情况下,可以通过CSS的:hover伪类来实现: 假如你想设定的固定区域为:<div id="test"></div>,那么只需要在CSS样式 ...

  7. A SQLiteConnection object for database '/data/data/.../databases/....db' was leaked!

      详细异常: A SQLiteConnection object for database '/data/data/.../databases/....db' was leaked!  Please ...

  8. css学习笔记之图像

    图像与文本的对齐方式: vertical-align:text-top;表示的意思是图像的顶部和同一行的文本对齐,但文本不会超出图片的上边线. vertical-align:middle;表示的意思是 ...

  9. Php header()函数及其常见使用

    语法: Void header(string $string[,bool $replace=true [, int $http_response_code) 向客户端发送原始的HTTP报头 需注意: ...

  10. 【转】使用Jmeter测试Webservice简单示例

    1.webservice 先简单开发webservice,参考文档 http://www.cnblogs.com/xwdreamer/archive/2011/12/07/2296914.html w ...