java io流和File类
输入/输出是所有程序都必须的部分,程序读取数据、用户输入数据、记录程序运行状态等……
输入流:分为字符输入流和字节输入流;
输出流:分为字符输出流和字节输出流;
那么字符流和字节流有什么区别呢:实现上 字节输出流是继承OutputStream 而字符输出流继承OutputStreamWriter(输入以此类推);在应用上 字符流是专门用来处理文字的,包含了对多国语言的支持,而字节流主要是用来处理文字以外的如binary文件。
而对于文件和目录都使用File来操作,以下列出File类的几种常用方法
- String getName(): 返回File对象所表示的文件名或者路径名(如果是路径,则返回最后一级子路径名)
- String getPath(): 返回File对象对应的路径名
- String getAbsolutePath():返回File对象的绝对路径名(File对象如果是送入一个相对路径,通过这个可以获取绝对路径
- String getParent(): 返回File对象对应目录的父目录名
- boolean renameTo(File newName):重命名File对象
- boolean createNewFile() 创建新的文件
- boolean delete() 删除File对象所对应的文件
- void deleteOnExit() jvm退出的时候删除File对象所对应的文件和目录
- boolean mkdir() 创建目录
- String[] list() 列出File对象的所有子文件名和路径名,返回String数组
- File[] listFile() 列出File对象的所有子文件和路径,返回File数组
通过递归获取某个目录的所有子文件
import java.io.File;
import org.junit.Test;
public class FindAllFile {
private String path = "E:\\DownLoad";
@Test
public void test(){
getAllFile(path);
}
private void getAllFile(String path) {
File file = new File(path);
//有文件时才操作
if(file.exists()){
File[] listFiles = file.listFiles();
for (File subFile : listFiles) {
//是目录继续进入
if (subFile.isDirectory()) {
getAllFile(subFile.getPath());
}else{
System.out.println(subFile.getName());
}
}
}else{
System.out.println("目录不存在");
}
}
}
IO流
- 输入流:只能从中读取数据:InputStream(字节流) 和 Reader(字符流)
- 字节流:由于InputStream是接口,使用实现类FileInputStream
- FileInputStream类的读取(下面代码)
public void copyFile(String path){
InputStream inputStream = null;
try {
inputStream = new FileInputStream(path);
byte[] by = new byte[1024];
int len1 = inputStream.read();//从输入流中读取单个字节,返回所读取的字节数据
int len2 = inputStream.read(by);// 从输入流中最多读取by.length个字节的数据,并将其存储在字节数组by中,返回实际读取的字节数据
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
inputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
- 字节缓冲流:字节流一次读写一个数组的速度明显比一次读写一个字节的速度快很多,这是加入了数组这样的缓冲区效果,java本身在设计的时候,也考虑到了这样的设计思想,所以提供了字节缓冲区流
- BufferedInputStream类的读取(下面代码)
public void copyFile1(String path){
BufferedInputStream bis = null;
try {
bis = new BufferedInputStream(new FileInputStream(path));
byte[] by = new byte[1024];
int len = 0;
while((len = bis.read(by)) !=-1){
write(len);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
bis.close();
}
}
- 字符流:由于Reader是接口,使用实现类Reader
- FileReader类的读取(下面代码)
public void copyFile(String path){
Reader reader = null;
try {
reader = new FileReader(path);
char[] cbuf = new char[1024];
int len1 = reader.read();//从输入流中读取单个字符,返回所读取的字符数据
int len2 = reader.read(cbuf);// 从输入流中最多读取cbuf个字符的数据,并将其存储在字符数组cbuf中,返回实际读取的字符数据
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
reader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
- 字符缓冲流:BufferedReader的读取(下面代码)
public void copyFile(String path){
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(path));
String len;
while((len = br.readLine()) !=null){
write(len);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
- 输出流:只能向其写入数据:OutputStream(字节流) 和 Writer(字符流)
- 输出流的写法和输入流基本一样
- OutputStream方法
void write(int c)// 将指定的字节输出到输出流中
void write(byte[] buf)// 将字节数组的数据输出到输出流中
- FileWriter方法
注意的一点:FileWriter(String fileName, boolean append) 这个构造方法(根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象,即可以追加写入文件)
void write(char[] buf)// 将指定字符数组的数据输出到输出流中
void write(String str)// 将str字符串里包含的字符输出到输出流中
- 字符缓冲流:BufferedWriter的写出(下面代码)
private void write(String len) {
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new FileWriter(path));//path写出的路径
bw.write(len);
bw.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
bw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
以上几个流都是节点流,关于其他流还有以下:
- 操作基本数据类型的流 :DataInputStream、DataOutputStream
- 随机访问流:RandomAccessFile类不属于流,是Object类的子类。但它融合了InputStream和OutputStream的功能。支持对随机访问文件的读取和写入。(等还有其他)
必须要注意的一点是:流必须要关闭,关闭流主要是为了释放资源,虽然java有自动回收垃圾资源的功能,但是如果不关闭流,可能会影响自动回收的效果,造成内存大量占用。另外一个重要的原因,如果不关闭流,可能会被其他的语句访问该数据流,造成数据错误。