-
-
- 一.File
- 二.FileInputStream&FileOutputStream
- 三.BufferedInputStream&BufferedOutputStream
- 四.捕捉异常并关闭IO流
- 五.InputStreamReader&OutputStreamWriter
- 六.FileReader&FileWriter
- 七.BufferedReader&BufferedWriter
- 八.LineNumberReader
- 九.SequenceInputStream
- 十.ByteArrayOutputStream
- 十一.DataInputStream&DataOutputStream
- 十二.RandomAccessFile
- 十三.ObjectInputStream&ObjectOutputStream
- 十四.Properties
-
一.File
1.路径
- 绝对路径:带盘符的完整路径
- 相对路径:相对于某个文件或目录的路径(Eclipse中相对于项目的根目录)
- Windows下目录分隔符可以是
\
或/
,Linux下只能是/
,建议统一使用/
或File.separator
- Windows路径不区分大小写,Linux下路径区分大小写
2.构造方法
File(String pathname)
- 使用文件或目录路径创建File对象
File(String parent, String child)
- 根据父目录路径和子目录或子文件路径创建File对象,
parent
与child
会进行字符串拼接
- 根据父目录路径和子目录或子文件路径创建File对象,
File(File parent, String child)
- 作用同上,父目录路径换成了File对象
3.成员方法
boolean createNewFile()
- 创建一个新文件,创建成功返回true,创建失败或者文件已存在则返回false
- 文件的每层父目录必须都存在,否则会抛出
java.io.IOException: 系统找不到指定的路径
boolean mkdir()
- 创建一个新目录,创建成功返回true,创建失败或者目录已存在或者父目录不存在则返回false
boolean mkdirs()
- 创建新目录,所有不存在的父目录也会被一起创建出来,创建成功返回true,创建失败或者目录已存在则返回false
boolean delete()
- 删除文件或目录,删除成功返回true, 路径不存在或者目录下存在子文件或目录都会返回false
- 文件或目录会被直接删除掉,不会放到回收站
boolean renameTo(File dest)
- 当目标路径与原路径是同一父目录时,则执行的是改名操作
- 当目标路径与原路径不是同一父目录时,则执行的是剪切并改名
- 如果目标路径的父目录不存在,则返回false
- 即使原目录下有子文件或目录,也可以成功被改名和剪切
- 重命名操作无法将一个文件从一个文件系统移动到另一个文件系统,所以谨慎使用,可以用 apache的common-io包实现相同的功能
boolean isFile()
- 判断是否文件类型
boolean isDirectory()
- 判断是否目录类型
boolean isAbsolute()
- 判断创建对象时传入的路径是否绝对路径
boolean isHidden()
- 判断是否隐藏
boolean canRead()
- 判断是否可读
boolean canWrite()
- 判断是否可读
boolean exists()
- 判断是否存在
boolean setReadable(boolean readable)
- 设置只读状态,Windows下设置不可读会返回false,默认全部文件都是可读的
boolean setWritable(boolean writable)
- 设置可写状态
boolean setLastModified(long time)
- 设置文件最后一次修改的时间,单位毫秒
long length()
- 获取文件大小,单位:字节
long lastModified()
- 获取文件最后被修改的时间,单位:毫秒
String getAbsolutePath()
- 获取绝对路径,无论创建File对象时传入的是相对路径还是绝对路径,都会返回返回绝对路径
String getPath()
- 获取创建File对象时传入的路径
String getName()
- 获取文件名(带后缀)或目录名
String getParent()
- 返回父目录路径
String[] list(FilenameFilter filter)
- 获取当前目录下所有的子文件名(带后缀)或子目录名
- 过滤器用于过滤文件或目录名,匿名实现过滤器并重写方法,不填写参数时则不过滤
File[] listFiles(FileFilter filter)
- 获取当前目录下所有子文件或子目录File对象
- 过滤器用于过滤文件或目录名,匿名实现过滤器并重写方法,不填写参数时则不过滤
二.FileInputStream&FileOutputStream
1.构造方法
FileInputStream(String name|File file)
- 根据文件路径或者File对象创建字节输入流
- 如果文件不存在则抛出
java.io.FileNotFoundException
FileOutputStream(String name|File file, boolean append)
- 根据文件路径或者File对象创建字节输出流
- 如果文件不存在,则会自动创建,但父目录不存在时则会报错
- 当第二个参数为false或不填写时,则会覆盖原文件内容,参数为true时,则在文件末尾追究内容
2.成员方法
int read(byte[] b)
- 从文件输入流中读取数据进byte数组中
- 返回的是实际读取的字节数,返回值为-1表示已读取完毕
void write(byte[] b, int off, int len)
- 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流
void close()
- 关闭流,释放资源
3.复制文件例子
//创建字节输入流
FileInputStream fis=new FileInputStream("a.txt");
//创建字节输出流
FileOutputStream fos=new FileOutputStream("copy_a.txt");
//创建字节数组,用于临时存放读入的字节,效率比每次读取单个字节高(内存操作比IO操作快很多)
byte[] bs=new byte[1024*8];
//实际读入的字节数
int len;
//循环把数据读入到字节数组中,直到读取完毕
while((len=fis.read(bs))!=-1){
//把字节数组写入到文件中
//最后一次读取可能填满整个字节数组,所以需要把实际读取的写入文件
fos.write(bs, 0, len);
}
//关闭流,释放资源
fis.close();
fos.close();
三.BufferedInputStream&BufferedOutputStream
1.概述
BufferedInputStream是对FileInputStream的包装,自带缓冲区,自动根据缓冲区字节数判断进行文件读入缓冲区,而read()读取的是缓冲区,并非读取文件
FileInputStream可能会出现阻塞,而BufferedInputStream不会阻塞,效率稍高
BufferedOutputStream是对FileOutputStream的包装,write()是写入缓冲区,当缓冲区满了自动flush()把内容刷新写进文件中
BufferedInputStream与BufferedOutputStream的缓冲区不是同一个缓冲区,各自管理自己的
2.构造方法
BufferedInputStream(InputStream in, int size)
- 根据字节输入流创建缓冲字节输入流
- 第二个参数size表示缓冲区的大小,不填写时默认1024*8
BufferedOutputStream(OutputStream out, int size)
- 根据字节输出流创建缓冲字节输出流
- 第二个参数size表示缓冲区的大小,不填写时默认1024*8
3.成员方法
- 同FileInputStream&FileOutputStream
4.案例
- 复制任何类型的文件优先选择此方式
//创建字节输入流
FileInputStream fis=new FileInputStream("a.txt");
//创建字节输出流
FileOutputStream fos=new FileOutputStream("copy_a.txt");
//创建缓冲流
BufferedInputStream bis=new BufferedInputStream(fis);
BufferedOutputStream bos=new BufferedOutputStream(fos);
byte[] bs=new byte[1024];
int len;
//从BufferedInputStream缓冲区读取数据进字节数组中,当缓冲区没有数据时,会自动读取文件填充缓冲区
while((len=bis.read(bs))!=-1){
//写入数据到BufferedOutputStream缓冲区,当缓冲区满时,会自动写入到文件中
bos.write(bs, 0, len);
}
//关闭缓冲流,释放资源,字节流也会随着被关闭
bis.close();
//输出缓冲流关闭前会调用flush()把数据刷到文件中
bos.close();
四.捕捉异常并关闭IO流
1.普通方式
//声明流
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream("a.txt");
fos = new FileOutputStream("copy_a.txt");
byte[] bs = new byte[1024 * 8];
int len;
while ((len = fis.read(bs)) != -1) {
fos.write(bs, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
// 关闭输入流
if (fis != null) {
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
// 关闭输出流
if (fos != null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
2.jdk1.7+方式
jdk1.7提供了
try(对象创建代码区){普通代码区}
方式自动调用AutoCloseable
接口的close()
方法。而字节流顶层类InputStream和OutStream都实现了AutoCloseable
接口,并在重写方法close()
中添加了关闭流等操作,所以达到了自动关闭流效果。
try(
//实现了AutoCloseable接口的类创建对象放 在try()中
FileInputStream fis = new FileInputStream("a.txt");
FileOutputStream fos = new FileOutputStream("copy_a.txt");
){
//在try{}中可以访问try()中的对象
byte[] bs = new byte[1024 * 8];
int len;
while ((len = fis.read(bs)) != -1) {
fos.write(bs, 0, len);
}
}catch (Exception e) {
e.printStackTrace();
}
//不用手动关闭流,会自动关闭
五.InputStreamReader&OutputStreamWriter
1.概述
- 是字节流转换为字符流的桥梁
- 可以指定转换编码或使用系统默认编码(UTF-8字符占用3个字节,GBK字符占用2个字节)
2.构造方法
InputStreamReader(InputStream in, String charsetName)
- 根据字节输入流创建InputStreamReader对象
- charsetName可指定编码格式,如果为空则使用系统默认的编码,读取的文件编码与流编码要一致,否则可能出现乱码
OutputStreamWriter(OutputStream out, String charsetName)
- 根据字节输出流创建OutputStreamWriter对象
- charsetName可指定编码格式,如果为空则使用系统默认的编码,写入的文件编码与流编码要一致,否则可能出现乱码
3.成员方法
int read()
- 读取单个字符,如果读到流的末尾,则返回-1
- 返回的是Unicode码值,需要用char强转后才得到真正的字符
int read(char[] cbuf)
- 读取多个字符进数组中,如果读到流的末尾,则返回-1
- 返回值是实际读取的字符数
void close()
- 关闭流并释放关联的资源
void write(int c)
- 写入单个字符
void write(String str)
- 把字符串写入文件中
4.例子
//使用UTF-8编码把a.txt文件字节流转换为字符流
InputStreamReader isr=new InputStreamReader(new FileInputStream("a.txt"),"UTF-8");
//读取单个字符
int n=isr.read();
//关闭流
isr.close();
//把码值转换为字符
char c=(char)n;
if(c=='你'){
//使用GBK编码把字符流转换为字节流再追加在b.txt文件中
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("b.txt",true),"GBK");
//写入字符串
osw.write("你好");
//关闭流
osw.close();
}
六.FileReader&FileWriter
1.概述
- FileReader&FileWriter是InputStreamReader&OutputStreamWriter的子类,已经搭建好桥梁,可直接操作文件
- 不可指定编码格式,需要编码要用InputStreamReader&OutputStreamWriter
2.构造方法
FileReader(String fileName)
- 根据文件名创建FileReader对象
FileWriter(String fileName, boolean append)
- 根据文件名创建FileWriter对象
- 如果文件不存在,则会自动创建,但父目录不存在时则会报错
- 当第二个参数为false或不填写时,则会覆盖原文件内容,参数为true时,则在文件末尾追究内容
3.成员方法
- 同InputStreamReader&OutputStreamWriter
4.例子
//创建a.txt的字符输入流
FileReader fr=new FileReader("a.txt");
char[] cs=new char[10];
//读取多个字符进数组中
fr.read(cs);
//关闭流
fr.close();
if(cs.length>1){
//创建b.txt的字符输出流,并设置写入格式为追加内容
FileWriter fw=new FileWriter("b.txt",true);
//写入内容
fw.write("你好");
//关闭流
fw.close();
}
七.BufferedReader&BufferedWriter
1.概述
- 跟BufferedInputStream&BufferedOutputStream作用一样,一个是操作字节流,一个操作的是字符流
2.构造方法
BufferedReader(Reader in, int sz)
根据字符输入流创建缓冲字符输入流
- 第二个参数size表示缓冲区的大小,不填写时默认1024*8
BufferedWriter(Writer out, int sz)
- 根据字符输出流创建缓冲字符输出流
- 第二个参数size表示缓冲区的大小,不填写时默认1024*8
3.特有成员方法
String readLine()
- 读取一行文本 ,到达流的末尾返回null
void newLine()
- 写入一个换行符
4.例子
//根据c.txt的字符输入流创建缓冲字符输入流
BufferedReader br=new BufferedReader(new FileReader("c.txt"));
//根据d.txt的字符输出流创建缓冲字符输出流
BufferedWriter bw=new BufferedWriter(new FileWriter("d.txt"));
String line;
//循环读取每一行
while((line=br.readLine())!=null){
//把内容写入到文件中
bw.write(line);
//换行
bw.newLine();
}
//关闭流并释放关联的资源
br.close();
bw.close();
八.LineNumberReader
1.概述
- LineNumberReader是对BufferedReader扩展了行号功能
- 只有LineNumberReader类,没有LineNumberWriter类
2.构造方法
- 同BufferedReader
3.特有成员方法
-int getLineNumber()
- 获取当前行号
void setLineNumber(int lineNumber)
- 设置当前行号
- 行号只是一个标志的数字,并没有筛选行的功能,无论行号多少,都不会影响读取的内容
4.例子
LineNumberReader lnr=new LineNumberReader(new FileReader("c.txt"));
String line;
//设置当前行号为100(行号只是一个标志的数字,并没有筛选行的功能,无论行号多少,都不会影响读取的内容)
lnr.setLineNumber(100);
//每执行一次readLine()行号都会+1
while((line=lnr.readLine())!=null){
//获取行号
System.out.println(lnr.getLineNumber()+":"+line);
}
九.SequenceInputStream
1.概述
- 对多个字节输入流放进序列组合中,逐一执行相同的操作
- 当前面的流读取完毕,会自动切换到下一个流中
2.构造方法
SequenceInputStream(InputStream s1, InputStream s2)
- 合并两个输入字节流
SequenceInputStream(Enumeration<? extends InputStream> e)
- 使用枚举器合并多个输入字节流
3.例子
FileInputStream fis1=new FileInputStream("a1.txt");
FileInputStream fis2=new FileInputStream("a2.txt");
//把两个输入字节流传递进序列字符流中
SequenceInputStream sis=new SequenceInputStream(fis1,fis2);
//把a1.txt和a2.txt文件的内容合并到a3.txt中
FileOutputStream fos=new FileOutputStream("a3.txt");
int len;
byte[] arr=new byte[1024];
while((len=sis.read(arr))!=-1){
fos.write(arr, 0, len);
}
//关闭序列输入流和其相关的流
sis.close();
fos.close();
//创建多个输入字节流,分别关联不同的文件
FileInputStream fis1=new FileInputStream("b1.txt");
FileInputStream fis2=new FileInputStream("b2.txt");
FileInputStream fis3=new FileInputStream("b3.txt");
FileInputStream fis4=new FileInputStream("b4.txt");
//创建Vector集合
Vector<FileInputStream> list=new Vector<FileInputStream>();
//把多个输入字节流添加进集合中
list.add(fis1);
list.add(fis2);
list.add(fis3);
list.add(fis4);
//获取Vector集合的枚举器
Enumeration<FileInputStream> en=list.elements();
//把枚举器传递给序列字节流中
SequenceInputStream sis=new SequenceInputStream(en);
FileOutputStream fos=new FileOutputStream("b5.txt");
int len;
byte[] arr=new byte[1024];
while((len=sis.read(arr))!=-1){
fos.write(arr, 0, len);
}
sis.close();
fos.close();
十.ByteArrayOutputStream
1.概述
- 字节数组输出流,存在于内存中,是一个可变长度的缓冲区
2.构造方法
ByteArrayOutputStream(int size)
- 可指定缓冲区大小,不填写参数时使用默认的大小
3.成员方法
void write(byte[] b, int off, int len)
- 把字节数组的指定区间元素写入到内存输出流的缓冲区中
writeTo(OutputStream out)
- 把内存输出流缓冲区的内容写入到文件中
String toString(String charsetName)
- 把缓冲区内容使用指定编码转换成字符串 ,不填写参数时使用默认的编码
4.例子
FileInputStream fis=new FileInputStream("a.txt");
//创建内存输出流
ByteArrayOutputStream bos=new ByteArrayOutputStream();
byte[] arr=new byte[1024];
int len;
while((len=fis.read(arr))!=-1){
//读取a.txt的内容进内存输出流的缓冲区中
bos.write(arr,0,len);
}
fis.close();
//把缓冲区的内容转换为字符串
System.out.println(bos.toString());
//字节输出流
FileOutputStream fos=new FileOutputStream("to_a.txt");
//根据字节输出流把缓冲区内容写入的到文件中
bos.writeTo(fos);
fos.close();
//关闭内存输出流无效,因为它是存在内存中的,并没有与文件有直接关系,所以关不关闭都没有影响
bos.close();
十一.DataInputStream&DataOutputStream
FileOutputStream fos=new FileOutputStream("f.txt");
//创建数据输入流
DataOutputStream dos=new DataOutputStream(fos);
//写入整数
dos.writeInt(987);
//写入小数
dos.writeDouble(2.34);
//写入UTF-8编码格式写入字符串
dos.writeUTF("你好");
//关闭流和其相关的资源
dos.close();
FileInputStream fis=new FileInputStream("f.txt");
//创建数据输出流
DataInputStream dis=new DataInputStream(fis);
//读取整型
int num1=dis.readInt();
//读取小数
double num2=dis.readDouble();
//读取UTF字符串
String str=dis.readUTF();
//关闭流和其相关的资源
dis.close();
十二.RandomAccessFile
1.概述
- 整合了输入流和输出流
2.构造方法
RandomAccessFile(File file, String mode)
- 根据File对象创建RandomAccessFile对象
- mode表示打开文件模式,
r
表示只读,rw
表示读写,还有rws
和rwd
RandomAccessFile(String name, String mode)
- 根据文件路径创建RandomAccessFile对象
3.成员方法
int read()
int read(byte[] b)
boolean readBoolean()
char readChar()
double readDouble()
int readInt()
long readLong()
short readShort()
void write(int b)
void write(byte[] b)
void write(byte[] b, int off, int len)
void writeBoolean(boolean v)
void writeChar(int v)
void writeDouble(double v)
void writeFloat(float v)
void writeInt(int v)
void writeLong(long v)
void writeShort(int v)
void writeChars(String s)
String readLine()
- 读取一行内容
new String( raf.readLine().getBytes("ISO-8859-1"),"UTF-8")
解决中文乱码
long length()
- 获取文件大小,单位:字节
void seek(long pos)
- 设置读写位置 (以字节数为偏移量)
int skipBytes(int n)
- 从当前位置跳过指定字节,当n为负数,则不跳过
long getFilePointer()
- 获取读写位置 (以字节数为偏移量)
十三.ObjectInputStream&ObjectOutputStream
1.概述
- 对象输出输入流用于序列化引用类型和基本类型的数据
- 序列化的类需要实现Serializable接口
2.构造方法
ObjectInputStream(InputStream in)
ObjectOutputStream(OutputStream out)
3.成员方法
void writeInt(int val)
void writeObject(Object obj)
int readInt()
Object readObject()
4.例子
//序列化的类需要实现Serializable接口
public class Person implements Serializable{
//序列化的版本ID,用于区分序列化时的类和反序列化时的类是否发生更改
//实现Serializable接口也可以不声明ID,会自动编号
private static final long serialVersionUID = 1L;
}
Person p1=new Person("张三",23);
Person p2=new Person("李四",24);
Person p3=new Person("王五",25);
ArrayList<Person> list=new ArrayList<>();
list.add(p1);
list.add(p2);
list.add(p3);
//创建对象输出流
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("object.txt"));
//写出整型数据
oos.writeInt(1);
//写出对象
oos.writeObject(p1);
//写出集合
oos.writeObject(list);
//关闭流和其相关的资源
oos.close();
//创建对象输入流
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("object.txt"));
//写入顺序和读取顺序是一致的
//读取整型
int num=ois.readInt();
//读取对象
Person p=(Person)ois.readObject();
//读取集合
ArrayList<Person> pList=(ArrayList<Person>)ois.readObject();
//关闭流和其相关的资源
ois.close();
System.out.println(num);
System.out.println(p);
System.out.println(pList);
十四.Properties
1.概述
- Properties是属性键值对集合,键和值都是字符串,是Hashtable的子类,无序,不可重复
- Properties可以操作.properties属性文件
2.构造方法
Properties()
- 无参构造
3.成员方法
String getProperty(String key, String defaultValue)
- 根据键获取值
- defaultValue参数当键不存在时,则返回默认的defaultValue,当不填写该参数时,返回null
Object setProperty(String key, String value)
- 添加或修改键值
Enumeration<?> propertyNames()
- 获取所有的键
void load(Reader reader)
- 加载文件中的内容进属性集合中
void store(OutputStream out, String comments)
- 把属性集合写进文件中
- comments是注释说明,中文可能出现编码不对,注释最好手动在文件中添加
4.例子
#学生配置信息
#properties文件注释以#开头
#格式: 键=值
age=23
name=张三
//创建属性集合
Properties prop=new Properties();
//添加2个属性
prop.setProperty("name", "张三");
prop.setProperty("age", "23");
//把属性集合写入到properties文件中
prop.store(new FileWriter("config.properties"), null);
//把config.properties内容读入到属性集合中
prop.load(new FileReader("config.properties"));
//获取属性集合的所有键
Enumeration<String> en=(Enumeration<String>) prop.propertyNames();
//遍历所有键
while(en.hasMoreElements()){
//获取当前枚举的键
String key=en.nextElement();
//根据键获取值
String value=prop.getProperty(key);
System.out.println(key+"="+value);
}