IO流
通过数据流、序列化和文件系统提供系统输入和输出。流是一个很形象的概念,当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数据源可以是文件,内存,或是网络连接。类似的,当程序需要写入数据的时候,就会开启一个通向目的地的流。这时候你就可以想象数据好像在这其中“流”动一样。就如水流、电流一样,从一处通往另外一处。
java IO流体系
java.io.File:java程序中的此类的一个对象,就对应着硬盘中的一个文件或网络中的一个资源。File既可以表示一个文件,也可以表示一个目录,File类的对象是与平台无关的,File类针对的是文件或者目录,只能进行新建、删除、重名令、上层目录等这种面上的操作,真正设计到文件内容的访问读取等,File是无能为力的,只能使用IO流下提供的相应的输入输出流来实现。
常把File类的对象作为形参传递给相应的输入输出流的构造器中。
分类 | 字节输入流 | 字节输出流 | 字符输入流 | 字符输出流 |
---|---|---|---|---|
抽象基类 | InputStream | OutputStream | Reader | Writer |
访问文件 | FileInputStream | FileOutputStream | FileReader | FileWriter |
访问数组 | ByteArrayInputStream | ByteArrayOutputStream | CharArrayReader | CharArrayWriter |
访问管道 | PipedInputStream | PipedOutputStream | PipedReader | PipedWriter |
访问字符串 | StringReader | StringWriter | ||
缓冲流 | BufferedInputStream | BufferedOutputStream | BufferedReader | BufferedWriter |
转换流 | InputStreamReader | OutputStreamWriter | ||
对象流 | ObjectInputStrem | ObjectOutputStream | ||
FilterInputStream | FilterOutputStream | FilterReader | FilterWriter | |
打印流 | PrintStream | PrintWriter | ||
推回输入流 | PushbackInputStream | PushbackReader | ||
特殊流 | DataInputStream | DataOutputStream |
IO流的划分
- 按照流的流向不同(站在程序的角度来看):输入流、输出流
- 按照流中数据单位的不同:字节流、字符流(纯文本文件使用字符流,除此以外字节流)
- 按照流的角色不同:节点流、处理流(流直接作用在文件上的是节点流,也叫文件流(4个),除此以外都是处理流)
代码示例
java.io.File代码示例
package com.buerc.java.file;
import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.regex.Pattern;
import org.junit.Test;
public class FileTest {
private static ArrayList<String> list=new ArrayList<>();
@Test
public void test(){
listFileNames(File.separator+"home");
System.out.println(list.size());
for(String s:list){
if(getFileNameWithRegex("(./*)+(conf.xml)$",s)){
System.out.println(s);
}
}
getFileNameWithFilter("(./*)+(.log)$",File.separator+"home");
}
//迭代获取 如果是文件直接add,如果是目录,则迭代获取
public static void listFileNames(String fileName){
File file=new File(fileName);
if(file.exists()){
if(!file.isDirectory()){
list.add(file.getAbsolutePath());
}else{
File[] files=file.listFiles();
for(File f:files){
if(f.isDirectory()){
listFileNames(f.getAbsolutePath());
}else{
list.add(f.getAbsolutePath());
}
}
}
}else{
System.out.println(fileName+"文件不存在");
}
}
//过滤不符合条件的文件名
public static boolean getFileNameWithRegex(String regex,String fileName){
return Pattern.matches(regex, fileName);
}
//列出指定目录下的合法文件
public static void getFileNameWithFilter(String filterStr,String filePath){
File file=new File(filePath);
String[] files=file.list(new FilenameFilter(){
@Override
public boolean accept(File dir, String name) {
return Pattern.matches(filterStr, name);
}
});
for(String s:files){
System.out.println(s);
}
}
}
java.io体系下的其他的的操作高度相似,都是4个能够直接访问文件的类new一个对象后进行read和write操作,再者就是像缓冲流这种类包裹之后进行处理加速文件的读取。
FileInputStream和FileOutputStream
package com.buerc.file;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;
import org.junit.Test;
public class FileInputOutputStreamTest {
@Test
public void inputTest(){//这里最好使用try catch而不是方法处直接抛出异常,以防止后面的fis.close()执行不到,从而无法关闭io这种稀有资源
File file=new File(File.separator+"home"+File.separator+"hechao"+File.separator+"hs_err_pid3304.log");
FileInputStream fis=null;
try {
fis=new FileInputStream(file);
byte[] b=new byte[1024];
int len;
try {
while((len=fis.read(b))!=-1){
System.out.println(new String(b,0,len));
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally{
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Test
public void outputTest(){
FileOutputStream fos=null;
Scanner s=new Scanner(System.in);//键盘输入
try {
fos=new FileOutputStream(File.separator+"home"+File.separator+"hechao"+File.separator+"test.txt");
String str=s.nextLine();
while(!("e".equalsIgnoreCase(str)||"exit".equalsIgnoreCase(str))){
try {
fos.write(str.getBytes());
fos.write("\n".getBytes());
} catch (IOException e) {
e.printStackTrace();
}
str=s.nextLine();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally{
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
s.close();
}
}
@Test//文件复制
public void inputOutputTest() {
InputStream fis=null;
// FileInputStream fis=null;
FileOutputStream fos=null;
try {
// fis=new FileInputStream("hello.txt");//一定得存在不然抛FileNotFoundException,文件存在于项目路径下
fis=this.getClass().getClassLoader().getResourceAsStream("hello.txt");
fos=new FileOutputStream("hello_copy.txt");//可以不存在,存在就覆盖,不存在就新建,文件存在于src路径下
byte[] b=new byte[1024];
int len;
try {
while((len=fis.read(b))!=-1) {
fos.write(b, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
FileReader和FileWriter
package com.buerc.file;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import org.junit.Test;
public class FileReaderWriterTest {
@Test
public void readerTest() {
FileReader fr=null;
try {
fr=new FileReader("hello_copy.txt");
char[] c=new char[1024];
int len;
try {
while((len=fr.read(c))!=-1) {
System.out.println(new String(c,0,len));
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally {
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Test
public void writerTest() {
FileWriter fw=null;
try {
fw=new FileWriter("test.txt");
fw.write("javaIO基础总结");
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Test
public void readerWriterTest() {
FileReader fr=null;
FileWriter fw=null;
try {
fr=new FileReader("hello_copy.txt");
fw=new FileWriter("test.txt");
char[] c=new char[1024];
int len;
while((len=fr.read(c))!=-1) {
fw.write(c, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
这4个类作为节点流直接作用在文件上,两两一对,一对是字节流一对是字符流,作为最基本的四个类。下篇总结作用在节点流上的处理流。