Java I/O基础知识点

字节流

InputStream 常用方法

  • int read()
  • int read(byte[] b)
  • int read(byte[] b,int off,int len)
  • void close()

常用子类

  • FileInputStream

    FileInputStream字节流读取文件

package IO;
import java.io.FileInputStream;
public class Example01 {
	public static void main(String[] args) throws Exception {
			//创建一个文件输入流读取文件
			FileInputStream in = new FileInputStream("test.txt");
			int b;
			while((b=in.read())!=-1) {
				System.out.print((char)b);
			}
			//关闭流  对于I/O的操作容易引发异常 为了方便我们直接抛出最大的异常
			in.close();
	}
}

运行结果
在这里插入图片描述
OutputStream 常用方法

  • void write(int b)
  • void write(byte[] b)
  • void write(byte[] b,int off,int len)
  • void flush()
  • void close()
  • FileOutStream

    FileOutStream字节流写入文件

package IO;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class Example01 {
	public static void main(String[] args) throws Exception {
		//写入的时候使用true 表示内容追加写入 不会覆盖原内容
		//当文件不存在的时候   java会自动创建文件 
		FileOutputStream out = new FileOutputStream("test.txt",true);
		String str = "welcome to java";
		out.write(str.getBytes());
	
		//输出test.txt的内容
		FileInputStream in = new FileInputStream("test.txt");
		int b;
		while((b=in.read())!=-1) {
			System.out.print((char)b);
		}
		//如果不关闭流
		//那么硬盘上的文件可能操作失败 比如删除文件就可能不会成功
		in.close();
		out.close();
	}
}

运行结果
在这里插入图片描述

文件使用字节流copy

**学习了字节输入流和输出流就可以实现文件的拷贝了**

	实现照片的拷贝(和重命名)
	package IO;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class Example01 {
	public static void main(String[] args) throws Exception {
		//创建文件输入组流对象指定的目录下的文件(简单的说就是拷贝的文件)
		FileInputStream in = new FileInputStream("io1.PNG");
		//创建文件输出流对象将读取的文件内容写入到指定的文件中  
		//-----》拷贝顺便过程中可以重命名 也可以不重命名
		FileOutputStream out = new FileOutputStream("io2.PNG");		
			
		int len;
		long beginTime =System.currentTimeMillis();
		while((len=in.read())!=-1) {
			out.write(len);
		}	
		long endTime =  System.currentTimeMillis();
		System.out.println("拷贝成功,花了"+(endTime-beginTime)+"毫秒");
		in.close();
		out.close();		
	}
}

运行结果
在这里插入图片描述
在这里插入图片描述
由于拷贝的是照片,所以最好使用字节流
使用字符流可能会造成数据丢失,文件打不开

文件比较小,所以拷贝的很快,但是文件很大那怎么办呢?

  我们上面是一个一个一个字节复制的,效率比较低,不太合适大文件传输,然后就有了字节流缓存区。
  • 第一个 自定义缓存区

package IO;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class Example01 {
	public static void main(String[] args) throws Exception {
		//创建文件输入组流对象指定的目录下的文件(简单的说就是拷贝的文件)
		FileInputStream in = new FileInputStream("io1.PNG");
		//创建文件输出流对象将读取的文件内容写入到指定的文件中  -----》拷贝顺便过程中可以重命名 也可以不重命名
		FileOutputStream out = new FileOutputStream("io2.PNG");		
			
		int len;
		//定义一个长度为1024的字节数组
		//这个就是自己定义的缓存区
		//字节的byte 字符的char
		byte[] b = new byte[1024];
		long beginTime =System.currentTimeMillis();	
		//因为文件过小 所以时间可能会显示0毫秒 
		//为了展示效果 故意让程序睡100毫秒 最后减去
		Thread.sleep(100);//使程序睡100毫秒
		//通过循环将读取到的文件写入到新文件中
		while((len=in.read(b))!=-1) {
			//每次循环读取一次字节数组 就将读取的到的内容写入到文件
			out.write(b, 0, len);
		}
		long endTime =  System.currentTimeMillis();
		//计算循环拷贝的时间
		System.out.println("拷贝成功,花了"+(endTime-beginTime-100)+"毫秒");
		//每次使用最好关闭流
		in.close();
		out.close();
		
		/*
		 * 如果该路径下有相同文件的名字
		 * 那么程序将直接覆盖
		 */
	}
}

运行结果

在这里插入图片描述

上面我们使用的是自己定义的缓存区,java其实已经帮我们封装好了缓存区,实现的原理和自定义缓存区没有太大的差别,搞懂了自定义缓存区,java封装的那不就So seay 吗?

  • 第二个 使用java封装的缓存区

  • java提供了俩个带缓存区的字节流,BufferedInputStream和BufferedOutputStream。构造函数中存放的是接收InputStream和OutputStream的参数。
  • 缓存区使用方式之前没变,至少底层加了个数组去存放字节(和自定义缓存区一样)
 package IO;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class Example01 {
	public static void main(String[] args) throws Exception {
		//创建文件输入组流对象指定的目录下的文件(简单的说就是拷贝的文件)
		FileInputStream in = new FileInputStream("test.txt");
		//创建文件输出流对象将读取的文件内容写入到指定的文件中  -----》拷贝顺便过程中可以重命名 也可以不重命名
		FileOutputStream out = new FileOutputStream("test2.txt");		
		BufferedInputStream bin = new BufferedInputStream(in);	
		BufferedOutputStream bout = new BufferedOutputStream(out);
		int len;
		long beginTime =System.currentTimeMillis();	
		//因为文件过小 所以时间可能会显示0毫秒 
		//通过循环将读取到的文件写入到新文件中
		while((len=bin.read())!=-1) {
			//每次循环读取一次字节数组 就将读取的到的内容写入到文件
			out.write(len);
		}
		long endTime =  System.currentTimeMillis();
		//计算循环拷贝的时间
		System.out.println("拷贝成功,花了"+(endTime-beginTime)+"毫秒");
		//每次使用最好关闭流
		in.close();
		out.close();		
		/*
		 * 如果该路径下有相同文件的名字
		 * 那么程序将直接覆盖
		 */
	}
}	

运行结果 由于没有使用Thread.sleep(100) 加上文件过小 使用时间显示0毫秒,有兴趣的朋友可以使用比较30M左右的exe文件。那样效果会明显一点点。
在这里插入图片描述

字符流

字符流使用接口
Reader
Writer
常用方法和字节流类似

字符流常用子类

  • FileReader
  • FileWrite

FileWrite写入文件

package IO;
import java.io.FileWriter;
public class Example01 {
	public static void main(String[] args) throws Exception {
		//写入的时候 不论是字符还是字节 不需要在意文件是否 存在
		//如果文件不存在 java会自动帮我创建 
		//但是读取就不一样了 如果文件不存在 那么java就会抛出文件找不到的异常
		//true 表示追加  不会覆盖内容 flase 相反
		FileWriter fw = new FileWriter("D:\\D\\test.txt");
//		FileWriter fw = new FileWriter("D:\\D\\test.txt",true);
		fw.write("你只是一个过客\r\n");
		fw.write("陪着我伤心难过\r\n");
		System.out.println("写入成功!");
		//一定要关闭流,不然数据可能写不进去
		fw.close();
	}
}

运行结果
在这里插入图片描述

FileReader使用自定义缓存区copy文件

由于字符和字节操作基本类似,所有我们直接开始使用带缓存区的字符流copy文件

package IO;
import java.io.FileReader;
import java.io.FileWriter;
public class Example01 {
	public static void main(String[] args) throws Exception {
		//读取的时候如果文件不存在会抛出异常 
		//读文件
		FileReader fr = new FileReader("D:\\D\\test.txt");
		//写文件  copy的路径可以随意更换 
		//这里方便演示就写了当前文件 我换个名字就好了
		FileWriter fw = new FileWriter("D:\\D\\testcopy.txt");
		
		//创建自定义缓存区 
		char[] buff = new char[1024];
		int len;
		while((len=fr.read(buff))!=-1) {
			fw.write(buff, 0, len);
		}
		//我这里就不演示时间问题 
		//时间我在字节流就演示了
		System.out.println("写入成功!");
		//还是强调一下文件的关闭
		//不然数据可能写不进去
		//也要注意关闭顺序   
		fw.close();
		fr.close();
	}
}

运行结果
在这里插入图片描述

在这里就说的差不多了,因为字符和字节操作很多类似,我就不一 一叙述了。
我就说一下字节没有的。

使用字符流带缓存区copy文件

package IO;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
public class Example01 {
	public static void main(String[] args) throws Exception {
		//读取的时候如果文件不存在会抛出异常 
		//读文件
		FileReader fr = new FileReader("D:\\D\\test.txt");
		//写文件  copy的路径可以随意更换 
		//这里方便演示就写了当前文件 我换个名字就好了
		FileWriter fw = new FileWriter("D:\\D\\testcopy.txt");
		//使用java自带的缓存区
		BufferedReader bfr = new BufferedReader(fr);
		BufferedWriter bfw = new BufferedWriter(fw);
		//定义一个null的字符串
		String str = null;
		//每次读一行 
		//每次写一行
		//如果没有内容了 那么就返回null
		while((str=bfr.readLine())!=null) {
			//第一种写入内容加换行
			//bfw.write(str+"\r\n");
			
			//第二种写入换行			
			//在这里我推荐使用第二种 第一种不了解也可以
			bfw.write(str);
			bfw.newLine();		
		}
		
		System.out.println("写入成功!");
		//还是强调一下文件的关闭
		//不然数据可能写不进去
		//也要注意关闭顺序   
		bfw.close();
		bfr.close();
	}
}

转化流

字符流和字节流可以相互转化

这个了解一下就行了,知道字符流和字节流可以相互转化。其实你的可能没必要,我也觉得,但是它又确实存在。

package IO;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class Example01 {
	public static void main(String[] args) throws Exception {
		//创建字节流对象 获取文件
		FileInputStream in = new FileInputStream("D:\\D\\test.txt");
		//将字节流转化为字符流
		InputStreamReader isr = new InputStreamReader(in);
		//将字符流加缓存区
		BufferedReader bisr = new BufferedReader(isr);
		
		//原理同上
		FileOutputStream out = new FileOutputStream("D:\\D\\testcopy.txt");
		OutputStreamWriter osw = new OutputStreamWriter(out);
		BufferedWriter bosw = new BufferedWriter(osw);
		String str = null;
		//每次读写一行 内容没有就返回null
		while((str=bisr.readLine())!=null) {
			bosw.write(str);
			//写入一个换行
			bosw.newLine();
		}
		System.out.println("写入成功");
		bosw.close();
		bisr.close();
	}
}

运行结果
在这里插入图片描述

File类

构造方法

  • File(String pathname)
  • File(String parent,String child)
  • File(File parent,String child)

File常用的方法

boolean exists()  判断File对应的文件或者目录是否存在,存在true 不在false
boolean delete()  删除File对象对应的文件或者目录,若成功删除则true,否则返回flase
boolean createNewFile() 当文件对象不存在是,该方法将新建一个次File对象所指的新文件,若创建成功,返回true,否则false
String getName() 返回File对象表示的文件或者文件夹的名称
String getPath() 返回File对象的对应的路径
String getAbsolutePath() 返回File对应的绝对路径
String getParent() 返回Fiel对象对应目录的父目录(即返回的目录不包含最后一级子目录)
boolean canRead() 判断File对象对应的文件或者目录是否可读,若可读返回true,否则返回false
boolean canWrite() 判断File对象对应的文件或者目录是否可写,若可写则返回true,否则返回falase
boolean isFile() 判断File对象对应的是否是文件(不是目录),若是文件则返回true。否则返回false
boolean isDirectory() 判断File对象对应的是否是目录(不是文件),若是文件则返回true。否则返回false
boolean isAbslute() 判断File对象对应的文件或者目录是否是绝对路径
long lastModified() 返回1970年1月1日0时0分0秒到文件最后修改的时间的毫秒值
long length() 返回文件内容的长度
String[] list 列出指定文件目录的全部内容 只是列出其名称
String[] list(FilenameFilter filter) 接收一个FilenameFilter参数,通过该参数可以列出符合条件的文件
File[] listFiles() 返回一个包含了File对象所有子文件和目录的File数组

上面的这么多方法其实我也记不住,太多了,但是要认识,有几个需要记住的。那我列出几个经常使用的。

package IO;
import java.io.File;
public class Example01 {
	public static void main(String[] args) throws Exception {
		File file = new File("D:\\D\\test.txt");
		System.out.println("文件名称:"+file.getName());
		System.out.println("文件相对路径:"+file.getPath());
		System.out.println("文件绝对路径:"+file.getAbsolutePath());
		System.out.println("文件父路径:"+file.getParent());
		System.out.println(file.canRead()?"文件可读":"文件不可读");
		System.out.println(file.canWrite()?"文件可写":"文件不可写");
		System.out.println(file.isFile()?"是个文件":"不是文件");
		System.out.println(file.isDirectory()?"是个目录":"不是目录");
		System.out.println(file.isAbsolute()?"是个绝对路径":"不是绝对路径目录");
		System.out.println("最后修改时间为:"+file.lastModified());
		System.out.println("文件大小为:"+file.length()+"bytes");
		//文件的删除不经回收站 删除就找不回来了
		System.out.println("是否成功删除文件:"+file.delete())	
	}
}

运行结果
在这里插入图片描述

单个文件的遍历

package IO;
import java.io.File;
public class Example01 {

	public static void main(String[] args) throws Exception {	
		File file = new File("F:\\新建文件夹 - 副本 - 副本");
		for (File listFile : file.listFiles()) {
			if(listFile.isFile()) {
				System.out.println("文件名:"+listFile.getName());
			}else if(listFile.isDirectory()) {
				System.out.println("目录名:"+listFile.getName());
			}
		}
	}
}

运行结果
在这里插入图片描述

多个文件的遍历或者删除(递归)

  • 因为删除和遍历本质是差不多 我就不演示了)
package IO;
import java.io.File;
public class Example01 {
	public static int count;
	public static void listdir(File file) {
		File[] listFiles = file.listFiles();
		if(listFiles!=null) {
			for (File listFile : listFiles) {
				if(listFile.isDirectory()) {
					listdir(listFile);
				}
				//这个递归删除
				//listFile.delete();
				//这个是递归遍历目录和文件的绝对路径
				System.out.println(listFile.getAbsolutePath());
				count++;
			}
		}
	}
	public static void main(String[] args) throws Exception {	
		//F:\新建文件夹 - 副本 - 副本
		File file = new File("F:\\新建文件夹 - 副本 - 副本");
		listdir(file);
		System.out.println("一个有"+count+"文件和目录");		
	}
}

运行结果
在这里插入图片描述

文件的过滤

  • 只要txt文件
package IO;
import java.io.File;
import java.io.FilenameFilter;
import java.util.Arrays;
public class Example01 {

	public static void main(String[] args) throws Exception {	
		File file = new File("F:\\新建文件夹 - 副本 - 副本");
		if(file.isDirectory()) {
			String[] list = file.list(new FilenameFilter() {
				//返回一个boolean值
				//使用匿名内部类
				@Override
				public boolean accept(File dir, String name) {
					//只需要txt文件结尾的
					return name.endsWith(".txt");
				}
			});
			//这个是工具类  比较好用 推荐
			System.out.println((Arrays.toString(list)));
		}
	}
}

运行结果
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值