【JavaSE】文件操作---File丶FileInputStream丶BufferedInputStream丶InputStreamReader丶FileReader丶BufferedReader

一.File

1.路径
  • 绝对路径:带盘符的完整路径
  • 相对路径:相对于某个文件或目录的路径(Eclipse中相对于项目的根目录)
  • Windows下目录分隔符可以是\/,Linux下只能是/ ,建议统一使用/File.separator
  • Windows路径不区分大小写,Linux下路径区分大小写
2.构造方法
  • File(String pathname)
    • 使用文件或目录路径创建File对象
  • File(String parent, String child)
    • 根据父目录路径和子目录或子文件路径创建File对象,parentchild会进行字符串拼接
  • 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 表示读写,还有rwsrwd

  • 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);
	}
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值