Java中使用流来处理程序的输入和输出操作,流是一个抽象的概念,封装了程序数据于输入输出设备交换的底层细节。JavaIO中又将流分为字节流和字符流,字节流主要用于处理诸如图像,音频视频等二进制格式数据,而字符流主要用于处理文本字符等类型的输入输出。

1.字节输入流InputStream

输入流InputStream负责从各种数据/文件源产生输入,输入源包括:数组,字符串,文件,管道,一系列其他类型的流,以及网络连接产生的流等等。

常用字节输入流的主要类型:

(1).ByteArrayInputStream字节数组输入流:

主要功能:允许内存缓存作为输入流。

ByteArrayInputStream包含一个内部缓冲区,该缓冲区包含从流中读取的字节。内部计数器跟踪read()方法要提供的下一个字节。

注意:关闭ByteArrayInputStream无效,该类中的方法在关闭此流之后仍可被调用,而不会产生任何的IOException。

(2).FileInputStream文件输入流:

主要功能:从文件系统中的某个文件获得输入字节,用于读取诸如图像数据子类的原始字节流。若要读取字符流,请使用FileReader。

(3).PipedInputStream管道输入流:

主要功能:和管道输出流一起构成一个输入输出的管道,是管道的数据输入端。

管道输入流应该连接到管道输出流,管道输入流提供要写入管道输出流的所有数据字节。通常,这些数据有某个线程从PipedInputStream对象中读取,并有其他线程将其写入到相应的PipedOutputStream对象中。

注意:不建议PipedInputStream和PipedOutputStream对象使用单线程,因为这样可能死锁线程。管道输入流包含一个缓冲区,可以在缓冲区限定范围内将读操作和写操作分离开,如果先连接管道输出流提供数据字节的线程不再存在,则认为该管道已损坏。

(4).SequenceInputStream顺序输入流:

重要功能:将两个或多个输入流对象转换为一个单个输入流对象。

SequenceInputStream表示其他输入流的逻辑串联关系,它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,以此类推,直到到达包含的最后一个输入流的文件末尾为止。

(5).FilterInputStream过滤输入流:

主要功能:包含其他一些输入流,将这些被包含的输入流用作其基本数据源,它可以直接传输数据或者提供一些额外的功能。

常用的FilterInputStream是DataInputStream数据输入流,主要用于允许程序以与机器无关的方式从底层输入流中读取java基本数据类型。其常用的方法有readInt(),readBoolean(),readChar()等等。

2.字节输出流OutputStream:

和字节输入流相对应,字节输出流负责字节类型数据想目标文件或设备的输出。常见的字节输出流如下:

(1).ByteArrayOutputStream字节数组输出流:

主要功能:在内存中创建一个缓冲区,将接收到的数据放入该内存缓冲区中。

ByteArrayOutputStream实现了一个输出流,其中的数据被写入一个byte数组中。缓冲区会随着数据的不断写入而自动增长,可使用toByteArray()和toString()方法获取数据。

注意:和ByteArrayInputStream类似,关闭ByteArrayOutputStream也是无效的,此类中的方法在关闭此流后仍可被调用,而不会产生任何IOException。

(2).FileOutputStream文件输出流:

主要功能:将数据写入到指定文件中。

文件输出流是用于将数据写入File或FIleDescriptor的输出流,用于写入诸如图像数据之类的原始字节流,若要写入字符流,请使用FileWriter。

(3).PipedOutputStream管道输出流:

主要功能:连接管道输入流用来创建通信管道,管道输出流是管道数据输出端。

(4).FilterOutputStream过滤输出流:

主要功能:用于将已存在的输出流作为其基本数据接收器,可以直接传输数据或提供一些额外的处理。

常用的FIlterOutputStream是DataOutputStream数据输出流,它允许程序以适当的方式将java基本数据类型写入输出流中。其常用方法有writeInt(intV),writeChar(int v),writeByte(String s)等等。

3.字符流:

Java中得字节流只能针对字节类型数据,即支持处理8位的数据类型,由于java中的是Unicode码,即两个字节代表一个字符,于是在JDK1.1之后提供了字符流Reader和Writer。

字符流相关常用类如下:

(1).Reader:

用于读取字符串流的抽象类,子类必须实现的方法只有reader(char[],int, int)和close()。

(2).InputStreamReader:

是将字节输入流转换为字符输入流的转换器,它使用指定的字符集读取字节并将其解码为字符。即:字节——>字符。

它使用的字符集可以有名称指定或显式给定,也可以使用平台默认的字符集。

(3).Writer:

用于写入字符流的抽象类,子类必须实现的方法只有write(char[],int, int)和close()。

(4).OutputStreamWriter:

是将字符输出流转换为字节输出流的转换器,它使用指定的字符集将要写入流的字符编码成字节。即:字符——>字节。

4.综合使用java IO各种流:

Java IO中的各种流,很少单独使用,经常结合起来综合使用,既可以满足特定需求,又搞效。例子如下:

(1).使用缓冲流读取文件:

 import java.io.*;  

 public class BufferedInputFile{
public static String read(String filename) throws IOException{
//缓冲字符输入流
BufferedReader in = new BufferedReader(new FileReader(filename));
String s;
StringBuilder sb = new StringBuilder();
//每次读取文件中的一行
While((s = in.readLine()) != null){
sb.append(s + “\n”);
}
in.close();
return sb.toString();
}
public static void main(String[] args) throws IOException{
System.out.println(read(“BufferedInputFile.java”));
}
}

(2).读取内存中的字符串:

 import java.io.*;  

 public class MemoryInput{
public static void main(String[] args) throws IOException{
//将字符串包装为字符输入流
StringReader in = new StringReader(
BufferedInputFile.read(“BufferedInputFile.java”));
int c;
//读取字符输入流中的字符
while((c == in.read()) != -1){
System.out.println((char)c);
}
}
}

(3).数据输入/输出流:

 import java.io.*;  

 public class DataInputOutput{
public static void main(String[] args) thows IOException{
DataOutputStream out = new DataOutputStream(new BufferedOutputStream(
new FileOutputStream(“Data.txt”)));
out.writeDouble(3.14159);
out.writeUTF(“That was pi”);
out.writeDouble(1.41413);
out.writeUTF(“Square root of 2”);
out.close();
DataInputStream in = new DataInputStream(new BufferedInputStream(
new FileOutputStream(“Data.txt”)));
System.out.println(in.readDouble());
System.out.println(in.readUTF());
System.out.println(in.readDouble());
System.out.println(in.readUTF());
}
}

输出结果:

3.14159

That was pi

1.41413

Square root of 2

(4).文本文件输出流:

 import java.io.*;  

 public class TextFileOutput{
//输出文件名
static String file = “BasicFileOutput.out”;
public static void main(String[] args) throws IOException{
//将字符串先包装成字符串输入流,然后将字符串输入流再包装成缓冲字符输入流
BufferedReader in = new BufferedReader(new StringReader
(BufferedInputFile.read(“TextFileOutput.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();
}
}

(5).二进制文件读写:

 import java.io.*;  

 public class BinaryFileOutput{
//输出文件名
static String file = “BinaryFileOutput.out”;
public static void main(String[] args) throws IOException{
//将字符串先包装成字符串输入流,然后将字符串输入流再包装成缓冲字符输入流
BufferedInputStream in = new BufferedInputStream(
new FileInputStream(“TestFile.png”)));
//字符输出流
BufferedOutputStream out = new BufferedOutputStream (
new FileOutputStream(file));
byte[] buf = new byte[1024];
int n;
While((n = in.read(buf)) > 0){
out.write(buf, 0, n);
}
out.close();
}
}

Java编程思想学习(十三) java I/O的更多相关文章

  1. (Java编程思想)Thinking in Java

    1. 为什么突然想去研读<Thinking in Java>? 最近终于下定决心撸了一本<Thinking in Java>第四版,虽然在此之前我就久闻这本书的大名,但一直未曾 ...

  2. [Java编程思想-学习笔记]第3章 操作符

    3.1  更简单的打印语句 学习编程语言的通许遇到的第一个程序无非打印"Hello, world"了,然而在Java中要写成 System.out.println("He ...

  3. Java编程思想学习(八) 内部类

    可以将一个类的定义放在另一个类的定义内部,这就是内部类. 内部类的定义是简单的,但是它的语法确实很是复杂,让人不是很好理解.下面就内部类做一个小结. 一.内部类的分类 总的来讲内部类分为普通内部类,匿 ...

  4. java编程思想--学习心得

    学习Java编程思想,需要了解语言特性,对于各种名词,能够借助项目代码,解释其含义,不借助搜索工具,明白其在什么样场景下使用,会带来什么样的问题,能否避免这类问题. 学习的过程,与软件开发相同,一样是 ...

  5. Java编程思想学习(一)----对象导论中多态的理解

    1.1抽象过程 1)万物皆对象. 2)程序是对象的集合,他们通过发送消息来告知彼此所要求做的. 3)每个对象都有自己的由其他对象所构成的存储. 4)每个对象都拥有其类型. 5)某一特定类型的所有对象都 ...

  6. [Java编程思想-学习笔记]第1章 对象导论

    1.1  抽象过程 Java是一门面向对象的语言,它的一个优点在于只针对待解问题抽象,而不用为具体的计算机结构而烦心,这使得Java有完美的移植性,也即Java的口号"Write Once, ...

  7. Java编程思想学习(十) 正则表达式

    正则表达式是一种强大的文本处理工具,使用正则表达式我们可以以编程的方法,构造复杂的文本模式,并且对输入的字符串进行搜索.在我看来,所谓正则表达式就是我们自己定义一些规则,然后就可以验证输入的字符串是不 ...

  8. Java编程思想学习笔记——类型信息

    前言 运行时类型信息(RTTI:Runtime Type Information)使得我们可以在程序运行时发现和使用类型信息. Java在运行时识别对象和类的信息的方式: (1)一种是RTTI,它假定 ...

  9. Java编程思想学习笔记——注解

    前言 在Android开发的过程中,我们为了减少重复代码的编写,会使用类似ButterKnife,AndroidAnnotations 这类依赖注解库.代码示例如下: //不使用 Button btn ...

随机推荐

  1. UESTC 1227 & POJ 3667 Hotel

    非常细腻的线段树题目啊,后来还是有个细节写错了,查了一个晚上..就不分析了. 代码: #include <iostream> #include <cstdio> #includ ...

  2. 集合框架学习笔记<三>

    一些重要的区别 set与list的区别: set是无索引的,list是有索引的: ArrayList与LinkList的区别: 前者是基于数组实现的,后者是基于链表实现的: 两者的使用方法一样,但是在 ...

  3. 第23章 SEH结构化异常处理(3)_终止处理程序

    23.3 终止处理程序 23.3.1 程序的结构 (1)框架 __try{ //被保护的代码块 …… } __finally{ //终止处理 } (2)__try/__finally的特点 ①fina ...

  4. Fix "Missing Scripts"

    一.Missing Scripts(脚本引用丢失) 请看下面的两张图的Warn(脚本引用丢失),在某些情况下我们会遇到这个警告. 二.解决办法 参考资料 http://unitygems.com/la ...

  5. C++中的运算符重载

    首先思考以下几个问题: 1.什么是运算符重载? 2.为什么要重载运算符,它有什么用? 3.可以重载哪些运算符? 4.重载运算符有哪些规则? 一.基本概念 我们在程序中使用各种操作符,比如加(+).赋值 ...

  6. FMDB 使用方法

    优秀的第三方库,README 也是很优秀的,理解了 README,会对使用带来很多便利. ARC 和 MRC 项目中使用 ARC 还是 MRC,对使用 FMDB 都没有任何影响,FMDB 会在编译项目 ...

  7. project和task

    projects和tasks是Gradle中最重要的两个概念 任何一个Gradle构建狗屎一个或多个projects的组成.每个project包括许多可构建组成部分 什么是 project ? 一个j ...

  8. 由源码密码文件转转化成keystore

      1.android 源码目录build\target\product\security 取platform.pk8 platform.x509.pem放到一个目录下 E:\sign\convert ...

  9. 《深入理解计算机系统》深入实践之——vim深入研究

    vim 用户手册中,大部分的例子都是在讲 vim 如何高效编写代码,由此可见,vim 是一款面向于程序员的多功能编辑器,即使某些功能 vim 无法直接完成,借助其丰富的插件资源,必定可以达成目标,这就 ...

  10. 信息安全系统设计基础实验一 20135210&20135218

    北京电子科技学院(BESTI) 实     验    报     告 课程: 密码系统设计基础                                                     ...