day08 IO流

File类
一、扩展
1.在电脑中,什么是文件?什么是文件夹?
一般情况下,带有后缀名的是文件,不带后缀名的是文件夹

	2.文件或者文件夹存储在哪里?
		存储在硬盘上  //C盘   D盘。。。。
	
	3.我们怎么能知道文件的属性信息?
		右键 ------ 属性

	4.我们说万物皆对象,那么在Java中用哪个类来表示文件或者文件夹呢?
		File类


二、File类的构造方法
	1.File​(String pathname) 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。  
		//参数string指的就是你要表示的文件或者文件夹的路径
	
	2.File​(String parent, String child) 从父路径名字符串和子路径名字符串创建新的 File实例。 
		//参数有两个   第一个string:父路径名   第二个string:自路径名

	3.File​(File parent, String child) 从父抽象路径名和子路径名字符串创建新的 File实例。 
		//第一个参数File       第二个参数:String
			//相比较于第二个构造方法而言,parent可以调用File类的相关方法

	//问题:
		为什么File类没有无参构造?  
			因为我们的电脑里有千千万万个文件和文件夹,如果你不给路径,那么JVM就不知道你创建的File对象指的到底是哪个文件

‪	//注意事项
		1.目录之间的分隔符 \  在引号中必须写两个\\,如果使用户向左的斜杠/  那么只需要写一个
				//在Java中,字符串中第一次出现的 \ 代表的是转义的意思,转的是紧跟在\后面的那个字符。
			File f1 = new File("D:\\a.txt");
			File f2 = new File("D:/a.txt");

		2.目录的盘符是不区分大小写的
			File f1 = new File("D:\\a.txt");
			File f1 = new File("d:/a.txt");

三、File类的创建功能
	1.public boolean createNewFile()当具有该名称的文件不存在时,创建一个由该抽象路径名命名的新空"文件"   //创建的是文件
		代码实现:
			File f1 = new File("d:/qwe/a.txt");   //注意:要想创建a.txt,必须先保证这个文件所在的上一级文件夹是存在的
			System.out.println(f1.createNewFile());
		
	2.public boolean mkdir() 创建由此抽象路径名命名的"目录"  //创建的是单级文件夹
		// mk:make   dir: directory
		代码实现:
			File f1 = new File("D:\\bcd");
			boolean mkdir = f1.mkdir();
			System.out.println(mkdir);
		
	3.public boolean mkdirs() 创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录  //创建的是多级文件夹
		代码实现:
			File f2 = new File("D:/bcd/qwe");
			System.out.println(f2.mkdirs());

四、File类的判断和获取功能
		1.public boolean isDirectory() 测试此抽象路径名表示的File是否为目录 //判断是否是文件夹
		2.public boolean isFile() 测试此抽象路径名表示的File是否为文件  //判断是否是文件
		3.public boolean exists() 测试此抽象路径名表示的File是否存在 //判断file对象指向的文件是否真实存在

		4.public String getAbsolutePath() 返回此抽象路径名的"绝对路径"名字符串
			//绝对路径:指的是带盘符的路径
				代码实现:
					File f1 = new File("D:\\bcd\\a.txt");
					System.out.println(f1.getAbsolutePath());
		
		5.public String getPath() 将此抽象路径名转换为路径名字符串
			//获取的是创建对象的时候,构造方法中传递的字符串
		
		6.public String getName() 返回由此抽象路径名表示的文件或目录的名称  //获取的是文件或者文件夹的名称
		7.public String[] list() 返回此抽象路径名表示的目录中的文件和目录的名称字符串数组//获取文件夹下面所有的文件和者文件的名称
		8.public File[] listFiles() 返回此抽象路径名表示的目录中的文件和目录的File对象数组  获取文件夹下面所有的文件和者文件的对象

五、File类的删除功能
	1.绝对路径和相对路径问题  //☆☆☆☆☆
		绝对路径:指的是带盘符的路径
		相对路径:不带盘符的路径//☆☆☆☆☆
			//到底相对于谁?
				相对的是项目(在项目的下面),不是module,和module是平级关系
			
			项目(project)和模块(module)的区别?
				一个项目下可以有多个模块
				
	2.删除的相关方法		
		public boolean delete() 删除由此抽象路径名表示的文件或目录
			//注意事项:
				(1).在删除文件夹的时候,一定要保证该文件夹是空的
					File f1 = new File("D:/bcd");   //必须保证bcd文件夹为空,这个时候才能删除掉
					System.out.println(f1.delete());
		
				(2)java中的删除不走回车站
		
		
		
		
	
1.	File f1 = new File("G:\\a.txt"); 为什么这段代码运行后,g盘不会出现这个a.txt文件 f1.createNewFile(); 
而这段代码运行后才会产生这个a.txt文件 可不可以理解为 第一句是 告诉jvm我想要处理一个叫a.txt的文件 
第二句是 我确定要创建它了 我感觉如果格式是这样我就可以很容易理解了
(但这个是不对的) File f1 = new File(); f1.createNewFile("G:\\a.txt");

2.在创建File对象时,相对路径写法都有哪些( ) ./和../表示什么? 像这样的还有哪些? 
	*第一种:IO流中的相对路径,相对于当前项目(project)
	*类加载器中的相对路径
	*web前端中的相对路径

3.直接打印文件的对象名和调用getPath方法有什么不同?
//toString() getPath() 从结果看,这两个方法的返回值是一模一样的
推荐按照功能去用:
toString:需要查看file类的内部属性
getPath:需要查看构造方法的参数字符串表示形式

六、递归
	1.概念
		递归指的是方法定义中调用方法本身的现象   
			//递归是一种思想,出现在方法中
		
	2.注意事项
		递归一定要有出口。否则内存溢出   //死循环
		递归虽然有出口,但是递归的次数也不宜过多。否则内存溢出
			//System.out.println(f(200000000));

	3.递归的方法格式
		*递归一定要有出口   ---------- >在递归方法中,一定是有一个if判断语句的
		*方法定义中调用方法本身的现象---------->要有方法调用自己本身
			格式:
				public 返回值  方法名(参数列表){
					if(是否为出口){    //找到出口条件
						return 值;
					}else{
						方法调用自己本身    //方法调用自己本身的规则
					}
				}
	
	
	4.递归的好处
		代码的方法复杂度较低
	

	5.递归求阶乘的案例
		5! = 5x4x3x2x1
		4!=4x3x2x1
		3!=3x2x1
		2!=2x1
		1!=1
		
		出口条件:1!=1
		自己调用自己本身的规律:5! = 5* 4!

		代码实现:
			 public static int  jc(int i){
					if(i==1){    //找到出口条件
						return 1;
					}else{
					   return i*jc(i-1);   //方法调用自己本身的规则
					}
				}

	6.遍历目录案例
		需求:找出文件夹下面所有的文件的名称
			出口条件:如果找到的文件对象为文件(不是文件夹)
			调用自己本身的规则:如果是文件夹的话,需要递归调用自己

			代码实现:
				public static void getAllPath(File file){
					File[] files = file.listFiles();
					for (File f1 : files){    
						if (f1.isFile()){          //出口条件:如果是文件对象,直接打印路径
							System.out.println(f1.getAbsolutePath());
						}else{
							getAllPath(f1);   //自己调用自己的规则,如果文件夹内部还是一个文件夹,那么调用自己本身
						}
					}
				}

IO流
一、IO流的引入
File类的功能时可以创建、删除文件,还可以查看文件的相关属性,但是它无法查看文件的内部内容。如果说我想查看文件的内容,就要使用IO流

二、IO流的概述和分类
	1.IO流的概念
		I:in的意思,输入流
		O:out的意思,输出流
		流:在Java中华我们把数据的流向传输称为流
	
	2.IO流的分类
		(1)按照"数据"的流向    //站在代码的角度(内存)
			*输入流:读数据
			*输出流:写数据
		(2)按照数据类型来分
			*字节流
				字节输入流
				字节输出流
			*字符流
				字符输入流
				字符输出流
			
			//扩展:数据的两种状态
				(1)游离态数据
						运行在程序中(内存)的数据(特点:程序关闭之后,再次打开数据就没了)   //学生管理系统
				
				(2)持久化数据
						存储在硬盘上的数据(特点:程序关闭之后,再次打开的时候数据还在)//视频

	3.IO流的使用场景
		如果操作的是纯文本文件(指的是用记事本打开能看懂的),优先使用字符流
		如果操作的是图片、视频、音频等二进制文件。优先使用字节流
		如果不确定文件类型,优先使用字节流。字节流是万能的流

三、字节流写数据
	1.字节输出流的抽象根类
		public abstract class OutputStream 
			//抽象类
			
	2.具体子类
		public class FileOutputStream
			extends OutputStream

	3.构造方法 
		FileOutputStream​(String name) 创建文件输出流以指定的名称写入文件。 
				//参数name:代表的是要写入的文件的路径

			//注意事项:
				FileOutputStream fos = new FileOutputStream("day08/a.txt");
					*如果a.txt不存在,那么执行上面这行代码就会默认帮我们去创建
					*如果a.txt已经存在,那么会把该文件中的内容全部清空   //☆☆☆☆☆

	4.写数据的方法
		void write​(int b) 将指定的字节写入此文件输出流。 
			//int类的参数b :需要的ASCII码
		
	5.释放资源
		void close​() 关闭此文件输出流并释放与此流相关联的任何系统资源。 
			//为什么要释放资源?
				int  i  = 10;
				System.out.println(i);//因为i都是存在于内存中,那么在使用完不使用的时候,会被垃圾回收器回收
				
				  FileOutputStream fos = new FileOutputStream("day08/a.txt");  //a.txt是持久态的数据,而持久态数据是存在于硬盘上的,不会消失
																					//所以和a.txt关联的fos就不会被自动释放,所以只能手动释放

	6.写数据的过程
		*创建字节输出流的对象(其实是把管道搭建在目标文件上)
		*调用写数据的方法
		*释放资源
			代码实现:
				FileOutputStream fos = new FileOutputStream("day08/a.txt");
				fos.write(97);
				fos.close();


	7.写数据的三种方式
		(1)void write​(int b) 将指定的字节写入此文件输出流。  
		(2)void write​(byte[] b) 将 b.length字节从指定的字节数组写入此文件输出流。  //就是因为数组里面可以存放多个字节,一次性输出多个字节,提供效率  
		(3)void write​(byte[] b, int off, int len) 将 len字节从指定的字节数组开始,从偏移量 off开始写入此文件输出流。//为了接下来赋复制文件做准备的

				//补充方法
					String--------- > 字节数组
					 例如:byte[] bytes = "xxx".getBytes();
					



四、字节流写数据的两个小问题
	1.换行
		windows:\r\n
			//   \r:这里的r是return的首字母,代表把光标移动到这一行的最前面
				\n: 这里的n是newline首字母,表示将光标移动到下一行
			
		linux:\n
		mac:\r
			//这里的换行针对的是系统自带的记事本
	
	2.追加写入
		FileOutputStream​(String name, boolean append) 创建文件输出流以指定的名称写入文件。 
			//参数append   如果传入true,就代表追加写入,如果为false,代表不追加


五、finally关键字
	*特点:finally代码块里面的程序一定会被执行,触发虚拟机退出
	
	*应用场景:
			//释放资源

	*异常的结构
		try{
			可能出现异常的代码
		}catch(异常名称 变量名){
			处理异常的代码
		}finally{
			一般是释放资源
		}
		
	异常的多种方式:	
	(1)try--catch--finally  //正确
	(2)try---finally   //正确
	(3)catch--finally   //错误
	(4)try---catch---catch--finally  //正确
		//try必须有,而且只能出现一次,   catch可以出现任意次   finally最多出现一次
		
六、字节流读数据
	1.字节输入流的抽象根类
		public abstract class InputStream
			//抽象类,不能直接创建对象

	2.具体子类 
		public class FileInputStream
			extends InputStream
		
	3.构造方法
		FileInputStream​(String name) 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。
			//参数  name :指的是需要读的那个文件的抽象路径
		
	4.读取数据的方法
		int read​() 从该输入流读取一个字节的数据。 
			//返回值  int  :返回的是从文件中读取到的数据     如果返回值-1,表示文件读完了
		
	5.循环读数据的步骤
		(1)创建字节输入流对象
		(2)循环读取数据
		(3)释放资源
			代码实现:
				public class Demo2 {
					public static void main(String[] args) throws IOException {
						FileInputStream fis = new FileInputStream("day08/a.txt");
						int len;
						while ((len=fis.read())!=-1){
							System.out.print((char) len);
						}
						fis.close();
					}
				}

	6.字节流赋值文本文件案例
		*复制"文件":  File类来创建的    //a.txt
		*复制"文件中的内容":  IO来操作
			代码实现:
				public class Demo4 {
					public static void main(String[] args) throws IOException {
						FileInputStream fis = new FileInputStream("day08/a.txt");
						FileOutputStream fos = new FileOutputStream(new File("day08/b.txt"));

						int len;
						while ((len=fis.read())!=-1){
							fos.write(len);
						}
						fos.close();
						fis.close();
					}
				}
							
	7.字节流一次读一个字节数组相关方法
		(1)int read​() 从该输入流读取一个字节的数据 
				//返回值:int指的是从文件中读取到的数据   如果返回值为-1,表示读取结束
		
		(2)int read​(byte[] b) 从该输入流读取最多 b.length个字节的数据到一个字节数组。
				//返回值 int指的是读取到的数据的长度    参数:byte[]这里面才是真正读取到的数据
					//数组的长度一般是1024的倍数?
						1K  = 1024 byte
						1M  = 1024K
						1G  = 1024M
						
		
		(3)int read​(byte[] b, int off, int len) 从该输入流读取最多 len个字节的数据到字节数组。
				//	//返回值 int指的是读取到的数据的长度    参数:byte[]这里面才是真正读取到的数据  ,off指的是数组开始索引   len指的长度
		
				//我怎么把读取到byte数组中的元素转换成String类型呢?
					byte[] -----------  > String
						例如: 
							String  s  =  new  String(bytes);
		
			问题:为什么读数据的时候,最后转换成字符串的时候用的0-len
				//因为如果最后一轮读取到的数据不是满数组,那么就可能多读了上一次的残留数据
		
	8.字节流复制图片案例
		public class CopyPic {
			public static void main(String[] args) throws IOException {
				FileInputStream fis = new FileInputStream("C:\\Users\\chun\\Desktop\\1.jpg");
				FileOutputStream fos = new FileOutputStream("day08/mn.jpg");

				int len;
				byte[] bytes = new byte[1024];
				while ((len=fis.read(bytes))!=-1){
					fos.write(bytes,0,len);
				}
				fos.close();
				fis.close();
			}
		}
			
//字节流小总结
	1.字节输入流
		*抽象根类:InputStream
			具体子类:FileInputStream
			
		*读数据的方法
			(1)int read​() 从该输入流读取一个字节的数据 
		
			(2)int read​(byte[] b) 从该输入流读取最多 b.length个字节的数据到一个字节数组。
						
			(3)int read​(byte[] b, int off, int len) 从该输入流读取最多 len个字节的数据到字节数组。
	
	2.字节输出流
		*抽象根类:OutputStream
			具体子类:FileOutputStream
	
		*写数据的方法 
			(1)void write​(int b) 将指定的字节写入此文件输出流。  
			(2)void write​(byte[] b) 将 b.length字节从指定的字节数组写入此文件输出流。   
			(3)void write​(byte[] b, int off, int len) 将 len字节从指定的字节数组开始,从偏移量 off开始写入此文件输出流。
	
	3.复制文件的方式
		(1)一次复制一个字节
			
		(2)一次复制一个字节数组
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值