思维导图
由于IO体系比较庞大,所以IO的知识分成4个部分进行归纳
这一篇主要写IO基础,红色的是基本流,其余为装饰流
一.IO的基础体系
IO是Input 和 Output的简称,这个jar包的主要功能就是实现数据的流通。
1.1File类
在介绍IO的具体类或接口以前,先介绍一个IO中常常会用到的类File,他表示文件或文件夹的对象。
import java.io.File;
import java.io.FilenameFilter;
import java.util.regex.Pattern;
public class IOdemo {
public static void main(String [] args){
//创建一个File,其路径为当前路径
File file = new File(".");
//常用的list()方法,列出当前目录中的文件和文件夹,返回到一个String数组中
String[] files = file.list();
//我们可以对名字进行进行过滤,只需写一个继承自FilenameFileter实现accept方法的类并放入list()中即可
String[] files = file.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
if(name.equals("out")){
return true;
}else{
return false;
}
}
});
//当然,也可以通过File类进行文件/文件夹的创建,重命名,删除,获得路径等操作,不做演示
for(String fileName: files){
System.out.println(fileName);
}
}
}
二.IO的体系
IO的体系大致有三个分叉,
- 字节流和字符流:字节流负责处理字节数据,字符流负责处理字符数据
- .输入流和输出流:一个处理出入,一个处理输出
- 基本流和修饰流:IO类采用的装饰器的设计模式,基本流负责接通数据源,修饰流则提供更丰富的功能
抽象模拟如图
2.1字节流的基本使用
//字节流的基本使用,主要功能是实现从e盘下的in.txt读取数据,然后输出到e盘下的out.txt
//首先,创建代表文件的对象
File inFile = new File("e:/in.txt");
File outFile = new File("e:/out.txt");
//然后创建基本流里的文件流
try {
//文件输入流
FileInputStream fis = new FileInputStream(inFile);
//输入流的装饰,选择有格式化阅读功能的装饰流
DataInputStream dis = new DataInputStream(fis);
//读取输入数据源的数据
StringBuffer data = new StringBuffer();
while(fis.available() != 0){
data.append((char)dis.read());
}
String getData =data.toString();
//文件输出流
FileOutputStream fos = new FileOutputStream(outFile);
//输出流的修饰,选择有格式化阅读功能的装饰流,和上边匹配
DataOutputStream dos = new DataOutputStream(fos);
//把数据输出到out.txt上
dos.writeUTF(getData);
//用完注意关闭
dis.close();
dos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
2.2字符流的使用
字符流是专用于处理字符的,所以可以直接读取文件中的字符,包括中文。
//字符流的基本使用,主要功能是实现从e盘下的in.txt读取数据,然后输出到e盘下的out.txt
//首先,创建代表文件的对象
File inFile = new File("e:/in.txt");
File outFile = new File("e:/out.txt");
//然后创建基本流里的文件流
//!!!!注意,字符输入输出流的本质是从字节流通过In/Out putStream Reader/Writer转化而来
try {
//文件输入流
FileReader fr = new FileReader(inFile);
//输入流的装饰,选择有缓冲功能的装饰流
BufferedReader br = new BufferedReader(fr);
//读取输入数据源的数据
StringBuffer data = new StringBuffer();
String s;
while((s = br.readLine()) != null){
data.append(s);
}
String getData =data.toString();
System.out.println(getData);
//文件输出流
FileWriter fw = new FileWriter(outFile);
//输出流的修饰,选择有缓冲功能的装饰流,和上边匹配
BufferedWriter bw = new BufferedWriter(fw);
//把数据输出到out.txt上
bw.write(getData);
//用完后,注意关闭流
br.close();
bw.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
2.3字节流转换为字符流
//字节流转换为字符流的基本使用,主要功能是实现从e盘下的in.txt读取数据,然后输出到e盘下的out.txt
//首先,创建代表文件的对象
File inFile = new File("e:/in.txt");
File outFile = new File("e:/out.txt");
//然后创建流
try {
//文件输入流
FileInputStream fi = new FileInputStream(inFile);
//字节流转换为字符流的工具
InputStreamReader ist = new InputStreamReader(fi);
//再加个缓冲修饰流
BufferedReader br = new BufferedReader(ist);
StringBuffer data = new StringBuffer();
String s;
while((s = br.readLine()) != null){
data.append(s);
}
String getData =data.toString();
System.out.println(getData);
//文件输出流
FileOutputStream fw = new FileOutputStream(outFile);
//字节流转换为字符流的工具
OutputStreamWriter osw = new OutputStreamWriter(fw);
//再加个缓冲修饰流
BufferedWriter bw = new BufferedWriter(osw);
//把数据输出到out.txt上
bw.write(getData);
//用完后,注意关闭流
br.close();
bw.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
三;独立的组合类:RandoAccessFile
这个类独立于字符流和字节流的体系之外,在功能上可以看作是输入流和输入流的组合,而且可以读取字符。
try {
//首先创建一个RandomAccessFile,先配置文件源,r是阅读权限
RandomAccessFile raf = new RandomAccessFile(new File("e:/in.txt"),"r");
StringBuilder sb = new StringBuilder();
String s;
while((s = raf.readLine()) != null){
//RandomAccessFile 读写文件时,不管文件中保存的数据编码格式是什么
//使用 RandomAccessFile对象方法的 readLine()
// 都会将编码格式转换成 ISO-8859-1 所以 输出显示是还要在进行一次转码
sb.append(new String(s.getBytes("ISO-8859-1"),"UTF-8"));
}
raf.close();
System.out.println(sb.toString());
//rw是读和写的权限
raf = new RandomAccessFile(new File("e:/out.txt"),"rw");
raf.writeUTF(sb.toString());
raf.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch(IOException e){
e.printStackTrace();
}
四.其他使用方式
4.1标准IO
Java本身内置了标准IO,即System.out,System.in,System.err,其中,System.in需要重新包装一下,键盘输入信息就会发送到System.in中。
标准IO可以重新定向,即让标准IO指向其他流对象。只需要使用System.setIn,System.setOut,System.setErr就可以了。
4.2进程控制
可以在Java中新建一个进程,使其运行命令,然后获取它的输入流或错误流,并输出。
try {
//开启另外一个线程,cmd指打开cmd命令行,/c指运行命令后结束,/k指运行后继续,Java则是输入的java命令。
Process pro = Runtime.getRuntime().exec("cmd /c java");
//创建输入流并于新建的线程对接
BufferedReader bre = new BufferedReader(new InputStreamReader(pro.getErrorStream()));
String s;
while((s = bre.readLine()) != null){
System.out.println(s);
}
bre.close();
} catch (IOException e) {
e.printStackTrace();
}