1.流
java.io包有两个主要部分:字符流和字节流。字符是指16位的UTF-16字符,而字节通常是8位的。字符流主要用于基于文本的I/O,而字节流主要用于基于二进制数据的I/O。字节流被称为输入流(input stream)与输出流(output stream),而字符流被称为读取器(reader)与写入器(writer)。
InputStream类是java.io包中大多数字节输入流的超类。主要方法有:
public abstract int read()throw IOException:从输入流中读取数据的下一个字节。返回 0
到 255
范围内的 int
字节值。如果因为已经到达流末尾而没有可用的字节,则返回值 -1
。在输入数据可用、检测到流末尾或者抛出异常前,此方法一直阻塞。
public int read(byte[] buf, int offset, int count)throws IOException:将输入流中最多count个数据字节读入byte 数组。尝试读取count个字节,但读取的字节也可能小于该值。以整数形式返回实际读取的字节数。在输入数据可用、检测到流末尾或者抛出异常前,此方法一直阻塞。如果count为0,则不读取任何字节并返回 0
;否则,尝试读取至少一个字节。如果因为流位于文件末尾而没有可用的字节,则返回值 -1
;否则,至少读取一个字节并将其存储在buf中。将读取的第一个字节存储在元素buf[offset]中,下一个存储在buf[offset+1]中,依次类推。读取的字节数最多等于count。设k为实际读取的字节数;这些字节将存储在buf[offset]到buf[offset+k-1]的元素中,不影响buf[offset+k]到buf[offset+count-1]的元素。
public int read(byte[] buf)throws IOException:等价于read(buf, 0, buf.length)。
public void close()throws IOException:关闭输入流。
OutputStream类是表示输出字节流的所有类的超类。主要方法有:
public abstract void write(int b)throws IOException:将指定的字节写入此输出流。要写入的字节是参数b的低8位,高24位将被忽略。
public void write(byte[] buf, int offset, int count)throws IOException:将指定byte数组中从偏移量offset开始的count个字节写入此输出流。
public void write(byte[] buf)throws IOException:等价于write(byte[] buf, 0, buf.length)。
public void flush()throws IOException:刷新此输出流并强制写出所有缓冲的输出字节。
public void close()throws IOException:关闭输出流。
用于读取或者写入字符流的抽象类是Reader和Writer。Reader类的主要方法:
public int read()throws IOException:读取单个字符。在字符可用、发生I/O 错误或者已到达流的末尾前,此方法一直阻塞。
public abstract int read(char[] buf, int offset, int count)throws IOException:将字符读入为char数组的一部分。在某个输入可用、发生 I/O 错误或者到达流的末尾前,此方法一直阻塞。
public int read(char[] buf)throws IOException:等价于read(char[] buf, 0, buf.length)。
public abstract void close()throws IOException:关闭输入流。
Writer类的主要方法:
public void write(int ch)throws IOException:写入单个字符。要写入的字符包含在给定整数值的低16位中,高16位被忽略。
public abstract void write(char[] buf, int offset, int count)throws IOException:写入字符数组的某一部分。
public void write(char[] buf)throws IOException:等价于write(buf, 0, buf.length)。
public void write(String str, int offset, int count)throws IOException:写入字符串的某一部分。
public void write(String str)throws IOException:等价于write(str, 0, str.length())。
public abstract void flush()throws IOException:刷新流。
public abstract void close()throws IOException:关闭流。
InputStreamReader与OutStreamWrite是字符流与字节流转化的桥梁。InputStreamReader使用指定的字符集读取字节并将其解码为字符。每次调用 InputStreamReader 中的一个 read() 方法都会导致从底层输入流读取一个或多个字节。要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作所需的字节。OutputStreamWrite使用指定的字符集将要写入流中的字符编码成字节。
2.文件操作
File类是文件和目录的路径名的抽象表示形式。
import java.io.File;
import java.util.Date;
/**
* 获取文件的基本信息
*/
public class GetFileInfos {
public static void println(String s){
System.out.println(s);
}
public static void main(String[] args) {
//用文件路径新建一个文件对象。路径可以是绝对路径也可以是相对路径
//传入的参数被当作为文件的抽象路径
File file = new File("C:/temp/newTemp.txt");
//获取文件的名字,不包括路径
println("文件名:\t" + file.getName());
//将抽象路径名中的文件分隔符用系统默认分隔符替换
println("文件路径:\t" + file.getPath());
//获取文件的绝对路径
println("绝对路径:\t" + file.getAbsolutePath());
//获取抽象路径名的父抽象路径
println("父目录:\t" + file.getParent());
println("文件是否存在:\t" + file.exists());
println("是否可读:\t" + file.canRead());
println("是否可写:\t" + file.canWrite());
println("是否是隐藏文件:\t" + file.isHidden());
println("是否是普通文件:\t" + file.isFile());
println("是否是文件目录:\t" + file.isDirectory());
println("文件路径是否是绝对路径:\t" + file.isAbsolute());
println("文件路径的URI:\t" + file.toURI());
println("文件最后修改时间:\t" + new Date(file.lastModified()));
println("文件大小:\t" + file.length() + " bytes");
}
}
File类的list方法返回该目录下所有文件的文件名(不包含路径信息)。listFiles方法返回该目录下所有文件的File对象。FilenameFilter是文件名过滤器接口类,自定义的文件名过滤器必须实现该接口的accept方法。
import java.io.File;
import java.io.FilenameFilter;
public class ListFileUtil {
/**
* 这是一个内部类,实现了FilenameFilter接口,用于过滤文件
*/
static class MyFilenameFilter implements FilenameFilter{
//文件名后缀
private String suffix = "";
public MyFilenameFilter(String surfix){
this.suffix = surfix;
}
public boolean accept(File dir, String name) {
//如果文件名以surfix指定的后缀相同,便返回true,否则返回false
if (new File(dir, name).isFile()){
return name.endsWith(suffix);
}else{
//如果是文件夹,则直接返回true
return true;
}
}
}
/**
* 列出目录下所有文件包括子目录的文件路径
* @param dirName 文件夹的文件路径
*/
public static void listAllFiles(String dirName){
//如果dir不以文件分隔符结尾,自动添加文件分隔符。
if (!dirName.endsWith(File.separator)){
dirName = dirName + File.separator;
}
File dirFile = new File(dirName);
//如果dir对应的文件不存在,或者不是一个文件夹,则退出
if (!dirFile.exists() || (!dirFile.isDirectory())){
System.out.println("List失败!找不到目录:" + dirName);
return;
}
//列出源文件夹下所有文件(包括子目录)
File[] files = dirFile.listFiles();
for (int i = 0; i < files.length; i++){
if (files[i].isFile()){
System.out.println(files[i].getAbsolutePath() + " 是文件!");
}else if (files[i].isDirectory()){
System.out.println(files[i].getAbsolutePath() + " 是目录!");
ListFileUtil.listAllFiles(files[i].getAbsolutePath());
}
}
}
/**
* 列出目录中通过文件名过滤器过滤后的文件。
* @param filter 文件名过滤器对象
* @param dirName 目录名
*/
public static void listFilesByFilenameFilter(FilenameFilter filter, String dirName){
//如果dir不以文件分隔符结尾,自动添加文件分隔符。
if (!dirName.endsWith(File.separator)){
dirName = dirName + File.separator;
}
File dirFile = new File(dirName);
//如果dir对应的文件不存在,或者不是一个文件夹,则退出
if (!dirFile.exists() || (!dirFile.isDirectory())){
System.out.println("List失败!找不到目录:" + dirName);
return;
}
//列出源文件夹下所有文件(包括子目录)
File[] files = dirFile.listFiles(filter);
for (int i = 0; i < files.length; i++){
if (files[i].isFile()){
System.out.println(files[i].getAbsolutePath() + " 是文件!");
}else if (files[i].isDirectory()){
System.out.println(files[i].getAbsolutePath() + " 是目录!");
ListFileUtil.listFilesByFilenameFilter(filter, files[i].getAbsolutePath());
}
}
}
public static void main(String[] args) {
String dir = "C:/temp";
System.out.println((dir + "目录下的内容: "));
ListFileUtil.listAllFiles(dir);
System.out.println();
System.out.println("经过过滤器过滤后的内容:");
//新建一个文件名过滤器。参数为".txt"
FilenameFilter myFilenameFilter = new ListFileUtil.MyFilenameFilter(".txt");
ListFileUtil.listFilesByFilenameFilter(myFilenameFilter, dir);
}
}