IO流

在这里插入图片描述

上圖是字节流
下图是字符流
在这里插入图片描述
以下参考:
https://www.cnblogs.com/zhaoyanjun/p/6292384.html
流的概念和作用
流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。

IO流的分类
根据处理数据类型的不同分为:字符流和字节流
根据数据流向不同分为:输入流和输出流
字符流和字节流
字符流的由来: 因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。 字节流和字符流的区别:

读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。

字节流:一次读入或读出是8位二进制。
字符流:一次读入或读出是16位二进制。

设备上的数据无论是图片或者视频,文字,它们都以二进制存储的。二进制的最终都是以一个8位为数据单元进行体现,所以计算机中的最小数据单元就是字节。意味着,字节流可以处理设备上的所有数据,所以字节流一样可以处理字符数据。

结论:只要是处理纯文本数据,就优先考虑使用字符流。 除此之外都使用字节流。
输入流和输出流
输入流只能进行读操作,输出流只能进行写操作,程序中需要根据待传输数据的不同特性而使用不同的流。

输入字节流 InputStream
InputStream 是所有的输入字节流的父类,它是一个抽象类。
ByteArrayInputStream、StringBufferInputStream、FileInputStream 是三种基本的介质流,它们分别从Byte 数组、StringBuffer、和本地文件中读取数据。
PipedInputStream 是从与其它线程共用的管道中读取数据,与Piped 相关的知识后续单独介绍。
ObjectInputStream 和所有FilterInputStream 的子类都是装饰流(装饰器模式的主角)。
输出字节流 OutputStream
OutputStream 是所有的输出字节流的父类,它是一个抽象类。
ByteArrayOutputStream、FileOutputStream 是两种基本的介质流,它们分别向Byte 数组、和本地文件中写入数据。
PipedOutputStream 是向与其它线程共用的管道中写入数据。
ObjectOutputStream 和所有FilterOutputStream 的子类都是装饰流。
总结:

输入流:InputStream或者Reader:从文件中读到程序中;
输出流:OutputStream或者Writer:从程序中输出到文件中;

Byte Streams(字节流)
Java byte streams are used to perform input and output of 8-bit bytes. Though there are many classes related to byte streams but the most frequently used classes are , FileInputStream and FileOutputStream. Following is an example which makes use of these two classes to copy an input file into an output file:

import java.io.*;
public class CopyFile {
public static void main(String args[]) throws IOException
{
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream("E:\\practise\\input.txt");
out = new FileOutputStream("E:\\practise\\output.txt");
int c;
while ((c = in.read()) != -1) {
out.write(c);
}
}finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
}

Now let’s have a file input.txt with the following content:
This is test for copy file.
As a next step, compile above program and execute it, which will result in creating output.txt file with the same content as we have in input.txt. So let’s put above code in CopyFile.java file and do
the following:
$javac CopyFile.java
$java CopyFile

https://www.tutorialspoint.com/java/pdf/java_files_io.pdf
Character Streams 字符流
Java Byte streams are used to perform input and output of 8-bit bytes, where as Java Character streams are used to perform input and output for 16-bit unicode. Though there are many classes related to character streams but the most frequently used classes are , FileReader and FileWriter
Though internally FileReader uses FileInputStream and FileWriter uses
FileOutputStream but here major difference is that FileReader reads two bytes at a time and FileWriter writes two bytes at a time.
We can re-write above example which makes use of these two classes to copy an input file havingunicodecharacters into an output file:

import java.io.*;
public class CopyFile {
public static void main(String args[]) throws IOException
{
FileReader in = null;
FileWriter out = null;
try {
in = new FileReader("input.txt");
out = new FileWriter("output.txt");
int c;
while ((c = in.read()) != -1) {
out.write(c);
}
}finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
}

Now let’s have a file input.txt with the following content:
This is test for copy file.
Standard Streams
All the programming languages provide support for standard I/O where user’s program can take input from a keyboard and then produce output on the computer screen. If you are aware if C or C++ programming languages, then you must be aware of three standard devices STDIN, STDOUTand STDERR. Similar way Java provides following three standard streams Standard Input: This is used to feed the data to user’s program and usually a keyboard is used as standard input stream and represented as System.in.
Standard Output: This is used to output the data produced by the user’s program and usually a computer screen is used to standard output stream and represented as System.out.
Standard Error: This is used to output the error data produced by the user’s program and usually a computer screen is used to standard error stream and represented as System.err. Following is a simple program which creates InputStreamReader to read standard input stream until the user types a “q”:

import java.io.*;
public class ReadConsole {
public static void main(String args[]) throws IOException
{
InputStreamReader cin = null;
try {
cin = new InputStreamReader(System.in);
System.out.println("Enter characters, 'q' to quit.");
char c;
do {
c = (char) cin.read();
System.out.print(c);
} while(c != 'q');
}finally {
if (cin != null) {
cin.close();
}
}
}
}

Let’s keep above code in ReadConsole.java file and try to compile and execute it as below. This program continues reading and outputting same character until we press ‘q’:

$javac ReadConsole.java
$java ReadConsole
Enter characters, ‘q’ to quit.
1
1
e
e
q
q

节点流
节点流:直接与数据源相连,读入

或读出。
直接使用节点流,读写不方便,为了更快的读写文件,才有了处理流。
这里写图片描述

常用的节点流
父 类 :InputStream 、OutputStream、 Reader、 Writer
文 件 :FileInputStream 、 FileOutputStrean 、FileReader 、FileWriter 文件进行处理的节点流
数 组 :ByteArrayInputStream、 ByteArrayOutputStream、 CharArrayReader 、CharArrayWriter 对数组进行处理的节点流(对应的不再是文件,而是内存中的一个数组)
字符串 :StringReader、 StringWriter 对字符串进行处理的节点流
管 道 :PipedInputStream 、PipedOutputStream 、PipedReader 、PipedWriter 对管道进行处理的节点流
处理流
处理流和节点流一块使用,在节点流的基础上,再套接一层,套接在节点流上的就是处理流。如BufferedReader.处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接。
这里写图片描述

常用的处理流
缓冲流:BufferedInputStrean 、BufferedOutputStream、 BufferedReader、 BufferedWriter 增加缓冲功能,避免频繁读写硬盘。
转换流:InputStreamReader 、OutputStreamReader实现字节流和字符流之间的转换。
数据流: DataInputStream 、DataOutputStream 等-提供将基础数据类型写入到文件中,或者读取出来。
转换流
InputStreamReader 、OutputStreamWriter 要InputStream或OutputStream作为参数,实现从字节流到字符流的转换。

构造函数

InputStreamReader(InputStream); //通过构造函数初始化,使用的是本系统默认的编码表GBK。
InputStreamWriter(InputStream,String charSet); //通过该构造函数初始化,可以指定编码表。
OutputStreamWriter(OutputStream); //通过该构造函数初始化,使用的是本系统默认的编码表GBK。
OutputStreamwriter(OutputStream,String charSet); //通过该构造函数初始化,可以指定编码表。

PrintStream和PrintWriter的区别:
PrintStream在输出字符,将字符转换为字节时采用的是系统默认的编码格式,这样当数据传输另一个平台,而另一个平台使用另外一个编码格式解码时就会出现问题,存在不可控因素。而PrintWriter可以在传入Writer时可由程序员指定字符转换为字节时的编码格式,这样兼容性和可控性会更好。

作为处理流使用时,PrintStream只能封装OutputStream类型的字节流,而PrintWriter既可以封装OutputStream类型的字节流,还能够封装Writer类型的字符输出流并增强其功能。

PrintStream versus PrintWriter
https://www.freejavaguide.com/corejava-io.pdf
PrintStream is used to output Java data as text. It implements a number of methods for displaying textual representation of Java primitive data types.
You’ve probably used a PrintStream object since your earliest Java programming days.
System.out is a PrintStream object. Probably everyone has used that for debugging!
That being said, PrintStream has been superseded by PrintWriter in Java 1.1. The
constructors of this class have been deprecated, but the class itself has not because it is still used by the System.out and System.err standard output streams.
The methods in PrintStream and PrintWriter are very similar. PrintWriter does not
have methods for writing raw bytes, which PrintStream has.

Flushing
Both the PrintStream and PrintWriter classes employ flushing, which moves data from
the internal buffers to the output stream. Flushing is employed in two ways:

  • Automatic flushing, which says when you call println you get flushing
  • Without automatic flushing, which says flushing occurs only when the flush() method is called
    With the PrintStream class, if a new-line character was written, the output is flushed.
    With the PrintWriter class, if you enable automatic flushing, the output is flushed only when a println() method is invoked. The println() methods of PrintWriter use the System property line.separator instead of the new-line (\n) character that PrintStream uses.
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值