对于任何程序设计语言而言,输入输出(Input/Output)系统都是非常核心的功能。程序运行需要数据,数据的获取往往需要跟外部系统进行通信,外部系统可能是文件、数据库、其他程序、网络、IO设备等等。
输入(Input)指的是:可以让程序从外部系统获得数据(核心含义是“读”,读取外部数据)。如:
读取硬盘上的文件内容到程序。例如:播放器打开一个视频文件、word打开一个doc文件。
读取网络上某个位置内容到程序。
读取数据库系统的数据到程序。
读取某些硬件系统数据到程序。例如:车载电脑读取雷达扫描信息到程序;温控系统等。
输出(Output)指的是:程序输出数据给外部系统从而可以操作外部系统(核心含义是“写”,将数据写出到外部系统)。常见的应用有:
将数据写到硬盘中。例如:我们编辑完一个word文档后,将内容写到硬盘上进行保存。
将数据写到数据库系统中。例如:我们注册一个网站会员,实际就是后台程序向数据库中写入一条记录。
将数据写到某些硬件系统中。
流是一个抽象、动态的概念,是一连串连续动态的数据集合。
当程序需要读取数据源的数据时,就会通过IO流对象开启一个通向数据源的流,通过这个IO流对象的相关方法可以顺序读取数据源中的数据。
一个简单的流读取数据:
public class Test1 {
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("d:/x.txt"); // 内容是:abc
StringBuilder sb = new StringBuilder();
int temp = 0;
//当temp等于-1时,表示已经到了文件结尾,停止读取
while ((temp = fis.read()) != -1) {
sb.append((char) temp);
}
System.out.println(sb);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
//这种写法,保证了即使遇到异常情况,也会关闭流对象。
if (fis != null) {
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
IO流总结:
1. 按流的方向分类:
输入流:数据源到程序(InputStream、Reader读进来)。
输出流:程序到目的地(OutPutStream、Writer写出去)。
2. 按流的处理数据单元分类:
字节流:按照字节读取数据(InputStream、OutputStream),命名上以Stream结尾的流一般是字节流,如FileInputStream、FileOutputStream。
字符流:按照字符读取数据(Reader、Writer),命名上以Reader/Writer结尾的流一般是字符流,如FileReader、FileWriter。
3. 按流的功能分类:
节点流:可以直接从数据源或目的地读写数据,如FileInputStream、FileReader、DataInputStream等。
处理流:不直接连接到数据源或目的地,是”处理流的流”。通过对其他流的处理提高程序的性能,如BufferedInputStream、BufferedReader等。处理流也叫包装流。
4. IO的四个基本抽象类:InputStream、OutputStream、Reader、Writer
5. InputStream的实现类:
FileInputStream
ByteArrayInutStream
BufferedInputStream
DataInputStream
ObjectInputStream
6. OutputStream的实现类:
FileOutputStream
ByteArrayOutputStream
BufferedOutputStream
DataOutputStream
ObjectOutputStream
PrintStream
7. Reader的实现类
FileReader
BufferedReader
InputStreamReader
8. Writer的实现类
FileWriter
BufferedWriter
OutputStreamWriter
9. 把Java对象转换为字节序列的过程称为对象的序列化。
10. 把字节序列恢复为Java对象的过程称为对象的反序列化。
示例
利用文件字节流(FileInputStream/FileOutputStream)实现文件的复制
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class TestFileCopy {
public static void main(String[] args) {
//将a.txt内容拷贝到b.txt
copyFile("d:/a.txt", "d:/b.txt");
}
/**
* 将src文件的内容拷贝到dec文件
* @param src 源文件
* @param dec 目标文件
*/
static void copyFile(String src, String dec) {
FileInputStream fis = null;
FileOutputStream fos = null;
//为了提高效率,设置缓存数组!(读取的字节数据会暂存放到该字节数组中)
byte[] buffer = new byte[1024];
int temp = 0;
try {
fis = new FileInputStream(src);
fos = new FileOutputStream(dec);
//边读边写
//temp指的是本次读取的真实长度,temp等于-1时表示读取结束
while ((temp = fis.read(buffer)) != -1) {
/*将缓存数组中的数据写入文件中,注意:写入的是读取的真实长度;
*如果使用fos.write(buffer)方法,那么写入的长度将会是1024,即缓存
*数组的长度*/
fos.write(buffer, 0, temp);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//两个流需要分别关闭
try {
if (fos != null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (fis != null) {
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
使用文件字符流FileReader与FileWriter实现文本文件的复制
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class TestFileCopy2 {
public static void main(String[] args) {
// 写法和使用Stream基本一样。只不过,读取时是读取的字符。
FileReader fr = null;
FileWriter fw = null;
int len = 0;
try {
fr = new FileReader("d:/a.txt");
fw = new FileWriter("d:/d.txt");
//为了提高效率,创建缓冲用的字符数组
char[] buffer = new char[1024];
//边读边写
while ((len = fr.read(buffer)) != -1) {
fw.write(buffer, 0, len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fw != null) {
fw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (fr != null) {
fr.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
使用缓冲字节流BufferedInputStream和BufferedOutputStream实现文件的高效率复制
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class TestBufferedFileCopy1 {
public static void main(String[] args) {
copyFile1("D:/电影/华语/大陆/尚学堂传奇.mp4", "D:/电影/华语/大陆/尚学堂越
"+"来越传奇.mp4");
}
/**缓冲字节流实现的文件复制的方法*/
static void copyFile1(String src, String dec) {
FileInputStream fis = null;
BufferedInputStream bis = null;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
int temp = 0;
try {
fis = new FileInputStream(src);
fos = new FileOutputStream(dec);
//使用缓冲字节流包装文件字节流,增加缓冲功能,提高效率
//缓存区的大小(缓存数组的长度)默认是8192,也可以自己指定大小
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos);
while ((temp = bis.read()) != -1) {
bos.write(temp);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//注意:增加处理流后,注意流的关闭顺序!“后开的先关闭!”
try {
if (bos != null) {
bos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (bis != null) {
bis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (fos != null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (fis != null) {
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
使用缓冲字符流BufferedReader与BufferedWriter实现文本文件的复制
BufferedReader/BufferedWriter增加了缓存机制,大大提高了读写文本文件的效率,同时,提供了更方便的按行读取的方法:readLine(); 处理文本时,我们一般可以使用缓冲字符流。
1. readLine()方法是BufferedReader特有的方法,可以对文本文件进行更加方便的读取操作。
2. 写入一行后要记得使用newLine()方法换行。
public class TestBufferedFileCopy2 {
public static void main(String[] args) {
// 注:处理文本文件时,实际开发中可以用如下写法,简单高效!!
FileReader fr = null;
FileWriter fw = null;
BufferedReader br = null;
BufferedWriter bw = null;
String tempString = "";
try {
fr = new FileReader("d:/a.txt");
fw = new FileWriter("d:/d.txt");
//使用缓冲字符流进行包装
br = new BufferedReader(fr);
bw = new BufferedWriter(fw);
//BufferedReader提供了更方便的readLine()方法,直接按行读取文本
//br.readLine()方法的返回值是一个字符串对象,即文本中的一行内容
while ((tempString = br.readLine()) != null) {
//将读取的一行字符串写入文件中
bw.write(tempString);
//下次写入之前先换行,否则会在上一行后边继续追加,而不是另起一行
bw.newLine();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bw != null) {
bw.close();
}
} catch (IOException e1) {
e1.printStackTrace();
}
try {
if (br != null) {
br.close();
}
} catch (IOException e1) {
e1.printStackTrace();
}
try {
if (fw != null) {
fw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (fr != null) {
fr.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
©著作权归作者所有:来自51CTO博客作者huingsn的原创作品,如需转载,请注明出处,否则将追究法律责任