一、File类
1.1File类概述
I/O(Input/Output)指应用程序对设备的数据输入/输出。负责输入/输出的类都位于java.io包中。
File类中的java.io包是唯一代表磁盘本身文件的对象,定义了一些与平台无关的方法用于操作文件。
常用构造方法如下图。
常用方法如下图。
1.2遍历目录下的文件
File类的list()方法用于遍历指定目录下的所有文件。
提供重载的list(FilenameFilter filter)方法获取指定类型的文件。FilternameFilter是一个接口,称为文件过滤器,当中定义了一个抽象方法accept(File dir,String name)。在调用该方法时需要Filenamefilter,并在accept()方法中作出判断,从而获得指定类型的文件。
eg.
import java.io.File;
import java.io.FilenameFilter;
public class Main{
public static void main(String[] args)throws Exception{
File file = new File("D:");
FilenameFilter filter = new FilenameFilter(){
//实现accept方法
public boolean accpet(File dir, String name){
File currFile = new File(dir,name);
if(currFile.isFile()&&name.endsWith(".java")){
return true;
}else{
return false;
}
}
};
if(file.exists()){
String[] names = file.list(filter);
for(String name : names){
System.out.println(name);
}
}
}
}
如果想实现得到所有子目录下的File类型对象,需要使用listFiles()。该方法返回一个File对象数组,当对数组中的元素进行遍历时,如果元素中还有子目录遍历则使用递归。
eg.
import java.io.File;
public class Main{
public static void main(String[] args)throws Exception{
File file = new File("D:");
fileDir(file);
}
public static void fileDir(File dir){
File[] files = dir.listFiles();
for(File file : files){
if(file.isDirectory()){
fileDir(file);
}
System.out.println(file.getAbsolutePath());
}
}
}
1.3删除文件及目录
File类中的delete()方法只能删除一个指定的文件,假如File对象代表目录且包含子目录或文件,则不允许直接删除这个目录,需要使用递归。
eg.
import java.io.File;
public class Main{
public static void main(String[] args)throws Exception{
File file = new File("D:");
deleteDir(file);
}
public static void deleteDir(File dir){
if(dir.exists()){
File[] files = dir.listFiles();
for(File file : files){
if(file.isDirectory()){
deleteDir(file);
}else{
file.delete();
}
dir.delete;//删除完所有文件后删除目录
}
}
}
}
注意,删除目录是从虚拟机直接删除而不放入回收站,文件一旦删除就无法恢复。
二、字节流
2.1字节流的概念
计算字的所有文件都是以二进制(字节)形式存在的。为字节的输入/输出(I/O)流提供的一系列的流,统称为字节流,根据数据的传输方向可将其分为字节输入流和字节输出流。
JDK中提供了两个抽象类InputStream和OutputStream,他们是字节流的顶级父类,他们不能被实例化,子类结构如下图。
2.2FileInputStream
FileInputStream是InputStream的子类,是操作文件的字节输入流,专门用于读取文件中的数据。
常用方法如下图
eg.
import java.io.*;
public class Main{
public static void main(String[] args)throws Exception{
FileInputStream in = new FileInputStream("test.txt");
int b = 0;//定义变量b记住每次读取的一个字节
while(true){
b = in.read();
if(b == -1){
break;
}
System.out.println(b);
}
in.close();
}
}
2.3FileOutputStream
FileOutputStream是InputStream的子类,是操作文件的字节输出流,专门用于把数据写入文件。
常用方法如下图
注意,如果通过FileOutputStream向一个已经存在的文件中写入数据,那么么该文件中的数据首先会被清空再写入新数据。若希望在后面追加新内容,则可以使用FileOutputStream(String fileName, boolean append)来创建文件输出流对象,并把append参数的值设置为true。
eg.
import java.io.*;
public class Main{
public static void main(String[] args)throws Exception{
FileOutputStream out = new FileOutputStream("test.txt",true);
String str = "123";
byte b[] = str.getBytes();
for(int i = 0; i < b.length; i++){
out.write(b[i]);
}
out.close();
}
}
I/O流进行读写数据时可能发生I/O错误,由Java虚拟机自动封装成I/O Exception异常并抛出。
如果发生I/O错误,则close()方法无法执行,可以用try...finally来保证无论是否发生错误都能正常关闭。
eg.
finally{
try{
if(in != null){
in.close();
}
}catch(Exception e){
e.printStackTrace();
}
try{
if(out != null){
out.close();
}
}catch(Exception e){
e.printStackTrace();
}
}
2.4文件的复制
文件的复制需要通过输入流来读取文件中的数据,输出流将数据写入文件。
当通过流的方式复制文件时,为了提高效率可以定义一个字节数组作为缓冲区,一次性读取多个字节的数据并保存在字节数组中,然后将字节数组中的数据一次性写入文件。
eg.
import java.io.*;
public class Main{
public static void main(String[] args)throws Exception{
FileInputStream in = new FileInputStream("source.txt",true);
FileOutputStream out = new FileOutputStream("target.txt",true);
int len;
while((len = in.read() != -1){
out.write(len);
}
in.close();
out.close();
}
}
I/O提供两个带缓冲的字节流,BufferedInputStream和BufferedOutputStream,他们的构造方法中分别接受InputStream和Outputstream类型的参数作为对象。
eg.
import java.io.*;
public class Main{
public static void main(String[] args)throws Exception{
BufferedInputStream bis = new BufferedInputStream("source.txt",true);
BufferedputStream bos = new BufferedOutputStream("target.txt",true);
int len;
while((len = bis.read() != -1){
bos.write(len);
}
bis.close();
bos.close();
}
}
三、字符流
3.1字符流的概念
字符流有两个抽象的顶级父类,Reader和Writer,子类结构如下图。
3.2FileReader和FileWriter
FileReader读取文件中的字符。
eg.
import java.io.*;
public class Main{
public static void main(String[] args)throws Exception{
FileReader reader = new FileReader("test.txt");
int ch;//定义变量b记住每次读取的一个字节
while((ch = reader.read()) != -1){
System.out.println((char)ch);
}
reader.close();
}
}
注意,字符输入流的read()方法返回的是int类型的值,如果需要获得字符需要强制类型转换。
FileReader对象返回的字符流是char,InputStream对象返回的字符流是byte,这是两者之间最大的区别。
FileWriter写入字符。
eg.
import java.io.*;
public class Main{
public static void main(String[] args)throws Exception{
FileWriter writer = new FileWriter("test.txt",true);
String str = "123";
writer.write(str);
writer.close();
}
}
如果指定的文件不存在,则先创建再写入,如果存在,则先清空再写入。
如果想追加内容,则调用重载的构造方法。
3.3BufferedReader和BufferedWriter
包装流是对一个已存在的流进行包装来实现提高数据读写功能效率,字符流提供带缓冲区的包装流BufferedReader和BufferedWriter。
BufferedReader中的方法readLine()用于一次读取一行文本。
eg.
import java.io.*;
public class Main{
public static void main(String[] args)throws Exception{
FileReader reader = new FileReader("src.txt");
BufferedReader br = new BufferedReader(reader);
FileWriter writer = new FileWriter("des.txt");
BufferedWriter bw = new BufferedWriter(writer);
String str;
while((str = br.readLine() != null){
bw.write(str);
}
br.close();
bw.close();
}
}
注意,调用BufferedWriter的write()方法写入字符时,字符首先会被写入缓冲区。当缓冲区写满或调用close()方法时,缓冲区中的字符才会被写入目标文件。因此最后一定要调用close()方法,否则很可能导致部分存在缓冲区中的数据未被写入文件。
3.4InputSreamReader和OutputStreamWriter
JDK提供了两个类将字节流转换为字符流。
eg.
import java.io.*;
public class Main{
public static void main(String[] args)throws Exception{
FileInputStream in = new FileInputStream("src.txt");
InputStreamReader isr = new InputStreamReader(in);
FileOutputStream out = new FileOutputStream("des.txt");
OutputStreamWriter osw = new OutputStreamWriter(out);
int ch;
while((ch = isr.read() != -1){
osw.write(ch);
}
isr.close();
osw.close();
}
}
标签:Java,String,基础,File,close,new,public,字节
From: https://blog.csdn.net/fwputty/article/details/139200111