黑马程序员_【总结】_IO知识梳理2

IO知识梳理2


---------- android培训 java培训、期待与您交流! ---------- 

---------------------------------------------------------------------------------------------------------------------------------------------

1、File 重点方法
listRoots():列出 系统的盘符。
String list()     :列出该盘符下所有的文件夹、文件 保过隐藏部分。
list(FilenameFilter filter): 文件过滤,选出指定文件
File listFiles()  :比list()更常用,因为被封装为对象,所以可以获取其名字和长度
2、递归   函数自身调用自身。
这种表现形式,或者说编程手法,称为【递归。【函数自身调用自身。】】
3、递归注意事项:
1、限定条件。
2、要注意递归的次数,尽量避免内存溢出。
4、Properties  是 hashtable  的子类
也就是说它具备 map 集合的特点,而且他里面存储的【键值对】 都是字符串
5、打印流 : 可以直接操作输入流和文件。
PrintStream
PrintWriter
该流提供了打印方法,可以将各种数据类型的数据都原样打印。
6、合并--分割
SequenceInputStream(en)    en为枚举值
1、 SequenceInputStream 是合并流,参数接收一个枚举值
2、那么集合中,谁有枚举呢: Vector 
把流都装入到Vector 形成一个结合
3、 SequenceInputStream 接收枚举, 形成合并流。
4、 创建一个输入流,并关联文件。
-------------------------------------------------------
【1】
常用方法:
1、创建
boolean createNewFile();  在指定位置常见文件,
如果该文件已经存在,则不创建,返回false,
同输出流不一样,输出流建立文件,如果存在,则直接覆盖。
boolean mkdir():创建文件夹(只能是一级目录)
boolean mkdirs():创建多级文件夹(D:\\e\\aa\\ee\\dd)
2、删除
boolean delete(); 指定删除
void deleteonExit();  退出时,删除
3、判断
exists() 判断文件或目录【是否存在】。
isDirectory() 是否是目录
isFile() 是否是文件
isHidden() 是否是隐藏文件 (Java是不能使用隐藏文件的)
isAbsolute()  是否是绝对路径(E:\\2\\213\2.txt)
4、查找
String getName();  获取名称
getPath() :获取路径
getParent(): 获取路径  没有明确指定负目录,返回的是空
getAbsolutePath() 获取绝对路径。
long lastModifide() :返回最后修改的时间。[last,modifai]
long length()  :  文件大小。
---------
【重点的部分】
listRoots():列出 系统的盘符。
String list()     :列出该盘符下所有的文件夹、文件 保过隐藏部分。
list(FilenameFilter filter): 文件过滤,选出指定文件

File listFiles()  :比list()更常用,因为被封装为对象,所以可以获取其名字和长度
-----------------------------------
endsWith(".java") 筛选
renameTo(File dest) 
分隔符:File.separator      可以跨平台使用。
因为E:\\   跨平台性不强
【2】
递归 概念
函数自身调用自身。
这种表现形式,或者说编程手法,称为【递归。【函数自身调用自身。】】


递归注意:
1、限定条件。
2、要注意递归的次数,尽量避免内存溢出。


递归中不要建立集合,因为会自己调用自己会不断创建集合。
class $3FileDemo {
	public static void main(String[] args) {
		File dir = new File("E:\\yunyao\\edjava\\");
		//showDir(dir);
		//toBin(6);
		int sum = getSum(8000);
		sop(sum);
	}
	//递归运算示例2:
	public static int getSum(int n){
		//计算1234一次相加的和
		if(n == 1){
			return 1;
		}
		return n+getSum(n-1);
	}
	//递归运算示例:
	public static void toBin(int num){
		if(num>0){
			toBin(num /2 );
			//num = num /2 ;
			sop(num%2);
		}
	}
	public static void showDir(File dir){
		sop("-----------------------------------");
		sop(dir);
		sop("--------");
		File [] files = dir.listFiles();
		for(int i = 0; i<files.length; i++){
			if(files[i].isDirectory())
				showDir(files[i]);//【再次调用本功能】函数自身调用自身。
			else
				sop(files[i]+"::"+files[i].length());
		}
	}
	public static void sop(Object obj){
		System.out.println(obj);
	}
}
//最简单的递归:  a 调用b b调用c   c打印完后,打印b  然后打印a    
// 有这么一个规律:先进后出。(栈的规律也)
class Test{
	void showA(){
	showB();
	sop(A);
	}
	void showB(){
		showC();
		sop(B);
	}
	void showC(){
		sop(C);
	}
}
【3】
Properties
Properties  是 hashtable  的子类
也就是说它具备 map 集合的特点,而且他里面 存储的【键值对】 都是字符串

是集合中的 和 IO 技术相结合的容器

该对象的特点: 可以用于键值对象的配置文件
(因为配置文件都是存放与电脑,和集合是在内存中。Properties  诞生)

需求。 在指定目录下编写一个配置文件,然后把该文件中传入到Propertise中。
class $8Properties{
	public static void main(String[] args) throws IOException{
		File f = new File("E:\\bbc.txt");
		method_1(f);		
		method_2(f);//
		method_3(f);//
	}
	//修改某一个数值
	public static void method_3(File file)throws IOException{
		Properties prop = new Properties();
		FileInputStream fis = new FileInputStream(file);
		prop.load(fis);
		//当需要修改值时,发现setProperty方法只能修改集合中的值,而文件
		//	中并没有修改。查看API 发现store()方法和 load 方法对应:
		prop.setProperty("laopo","9");
		FileOutputStream fos = new FileOutputStream(file);//同样一个流
		prop.store(fos,"update");//同样传入流,后面是注释标题:
		prop.list(System.out);//列出Properties 建议用该方法。
		fis.close();
		fos.close();
	}
	//[method_1 终极进化模式。]
	public static void method_2(File file)throws IOException{
		Properties prop = new Properties();
		FileInputStream fis = new FileInputStream(file);
		prop.load(fis);//将集合中数据成对加载Properties 集合中。
		//System.out.println(prop);
		prop.list(System.out);//列出Properties 建议用该方法。
	}
	public static void method_1(File file)throws IOException{
		BufferedReader bufr = new BufferedReader(new FileReader(file));
		String line = null;
		Properties prop = new Properties();
		int index=0;
		while((line=bufr.readLine())!=null){
			if(line.contains("=")){   //只对键值对进行分割				 
				String [] str = line.split("=");
				prop.setProperty(str[0],str[1]);
			}
		}
		//查看是否成功将数据插入到Properties
		Set<String> set =prop.stringPropertyNames();
		for(String s : set ){
			System.out.println(s+"::"+prop.getProperty(s));
		}
	}
}
练习案例:
需求:
用于记录应用程序运行次数。
如果使用次数已到,那么给出注册提示。

通常会想到:计数器
但是该计数器定义在程序中,随着程序的运行而存在于内中,并进行自增
随着应用程序的退出,该计数器也会在内存中消失。

下一次在启动该程序,又会重新开始从0计数。
这样就达不到要求。

可以 创建一个 Properties 集合,设定一个计数器键值对。
打开某一个应用程序时,建立一个相对应的计数器集合。初始值为1
再次打开判断是否有该程序的计数器,没有,新建,有,值自增。
当这个值达到某个数值时,提示次数已满。 

1、接收文本目录,创建一个BufferedReader 关联文件
2、创建Pro 集合,根据文件名写入键值对。
3、主函数可以用一个循环,运行一次,调用一次计数。
4、输出次数。
public class IO3 {
	public static void main(String[] args) throws IOException{			
		Properties prop = new Properties();//1、创建集合
		File file = new File("E:\\cout.ini");//2、把文件封装为对象
		if(!file.exists()){  //3、判断文件是否存在
			file.createNewFile();  //3-1、如果没有该文件则创建一个。
		}
		FileInputStream fis = new FileInputStream(file); //4、建立读取流并关联文件
		prop.load(fis);        //5、载入。键值对数据。
		int count = 0;
		String value = prop.getProperty("Sum"); //6/获取  key  对应的值  value
		System.out.println("模拟启动");
		if(value!=null){	// 7、判断有没有该  key 
			count = Integer.parseInt(value);  //7-1、如果有则把 value 值转换为int
			if(count>=5){
				System.out.println("软件使用次数到期。交钱吧。");
				return ;
			}
		}
		count++;    //  8、自增一次。
		prop.setProperty("Sum",count+"");  // 9、 更新数据/一定要通过 count+"" 进行转换
		FileOutputStream fos = new FileOutputStream(file);  //10、建立输入流并关联文件
		prop.store(fos,"update");//11、更新到硬盘文件
		fis.close();//12、管理两个缓冲区。
		fos.close();
	}
}
【4】
打印流 : 可以直接操作输入流和文件。
PrintStream
PrintWriter
该流提供了打印方法,可以将各种数据类型的数据都原样打印。

字节打印流
PrintStream
构造函数可以接收的参数类型:
1、file对象
2、字符串路径 
3、字节输出流 OutputStream
字符打印流
PrintWriter
构造函数可以接收的参数类型:
1、file对象
2、字符串路径 
3、字节输出流 OutputStream
4、字符输出流  Writer
【5】 合并--分割
对多个流进行合并
SequenceInputStream(en)    en为枚举值
1、 SequenceInputStream 是合并流,参数接收一个枚举值
2、那么集合中,谁有枚举呢: Vector 
把流都装入到Vector 形成一个结合
3、 SequenceInputStream 接收枚举, 形成合并流。
4、 创建一个输入流,并关联文件。
//  Vector Enumeration elements  SequenceInputStream
实现两个功能:
1、分割
1、创建读取流并关联文件,声明读写流
源,电脑,视频文件: FileInputStream
2、创建一个byte 类型数组,大小为需求每个文件的大小
3、通过循环方式,new出读写流,并装入数据。
4、关闭所有流。
2、合并   
老方法:
1、因为合并流 SequenceInputStream  的参数必须是枚举,所以需要用到Vector
2、创建 Vector 新增被分割的文件。
3、枚举 Enumeration en  = v.elements
4、创建 SequenceInputStream 接收en
5、创建读写流 FileOutputStream 并管理文件位置。
6、记住 一个字节数组来存储,利用循环。
7、关闭所有流

方法2:
因为vector 方法效率很低,所以使用 ArrayList  来处理
因为 ArrayList 只有迭代没有枚举 所以,使用迭代 建立 枚举内部来来返回 转型。
注意,Enumeration 必须重载两个方法,hashCodeElements nextElement   
剩余步骤一致
//  Vector Enumeration SequenceInputStream hasMoreElements nextElement
class $93Test1 {
	public static void main(String[] args) throws Exception{
		File f = new File("E:\\Test\\mp4");
		spiltFile_1();                  //  切割
		Thread.sleep(2000);
		toSequenceInputStream_2(f);     //  合并
		//toSequenceInputStream_1(f);   //	 低效率合并--摒弃。
		Thread.sleep(3000);//延迟几秒再进行删除
		DeleteFile(f);                  //  删除
	}
	//【2】  发现分割出问题了,删除错误分割文件
	public static void DeleteFile(File dir)throws Exception	{
			try{
				File [] files = dir.listFiles();// 把接收到的路径对象 装入数组中
				for(File file : files){  // 递归 判断内部是否还包含文件夹
					if(file.isDirectory()){						
						DeleteFile(file);
					}
					System.out.println("Dele:"+file.delete());//  删除文件
				}
				System.out.println("OVER");
				//System.out.println("OVER\nDele:"+dir.delete());// 删除文件夹
			}
			catch (IOException e){
				throw new RuntimeException();
			}				
	}
	//【1】 分割
	public static void spiltFile_1(){
		FileInputStream fis =null;
		FileOutputStream fos = null;
		try{
			fis = new FileInputStream("E:\\207.mp4");//读写流 关联文件
			int len = 0;
			int count = 1;
			byte [] by = new byte[1024*1024*10];// 设置 10M
			while((len = fis.read(by))!=-1){
				fos = new FileOutputStream("E:\\Test\\mp4\\"+(count++)+".part");//创建一个写入流 并关联文件
				fos.write(by,0,len);//写入
				fos.close();//关闭该流        //循环后,count++   这个时候关联新的文件。
			}
			System.out.println("Spilt is Over!");
		}
		catch (IOException e){
			throw new RuntimeException();
		}
		finally{
			try{
				if(fis!=null)//切记关闭流
					fis.close();
			}
			catch (IOException e){
				throw new RuntimeException();
			}
		}			
	}
	//【3】 合并
	public static void toSequenceInputStream_2(File dir) throws IOException{
		SequenceInputStream sis =null;
		FileOutputStream fos =null;
		BufferedOutputStream bufi=null;
		try{
			ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();//  用该集合取代 低效的 vector 
			for(int i = 1; i<= 14 ; i++){
				al.add(new FileInputStream("E:\\Test\\mp4\\"+i+".part")); // 遍历新增 被分割的文件。
			}
			final Iterator<FileInputStream> it = al.iterator(); //  因为 ArrayList 没有枚举,只有迭代, 那么我们中转一下。 记住是 final 修饰

			Enumeration<FileInputStream> en = new Enumeration<FileInputStream>(){  //  枚举  通过内部类  通过 转换 使枚举 返回 迭代值
						public boolean hasMoreElements(){  // 切记覆盖该方法  boolean 类型
								return it.hasNext();
						}
						public FileInputStream nextElement(){ // 切记覆盖该方法  FileInputStrean 类型
								return it.next();
						}
			};
			sis = new SequenceInputStream(en);// SequenceInputStream  接收枚举
			//fos = new FileOutputStream("E:\\Test\\mp4\\2222.mp4");
			bufi =new BufferedOutputStream(new FileOutputStream("E:\\Test\\mp4\\2222.mp4")); //  为了效率
			int len = 0;
			byte [] by = new byte[1024];// 别忘了字节数组
			while((len = sis.read(by))!=-1){  //  读的是数组
				bufi.write(by,0,len);//fos.write(by,0,len); //  写入
				//bufi.flush();//fos.flush();                  // 刷新,其实可以不写。 因为接着就关闭了,自动刷新了。
			}
			System.out.println("Sequence is Over!");
		}
		catch (IOException e){
			throw new RuntimeException();
		}
		finally{
			try{
				if(bufi!=null) //切记关闭流
					bufi.close();
			}
			catch (IOException e)
			{
				throw new RuntimeException();
			}
			finally{
				try{
					if(sis!=null)//切记关闭流
						sis.close();
				}
				catch (IOException e)
				{
					throw new RuntimeException();
				}
			}
		}
	}
	// 使用 Vector  --  但是效率不好。 
	public static void toSequenceInputStream_1(File dir) throws IOException
	{
//		1、因为合并流 SequenceInputStream  的参数必须是枚举,所以需要用到Vector
//		2、创建 Vector 新增被分割的文件。
//		3、枚举 Enumeration en  = v.elements
//		4、创建 SequenceInputStream 接收en
//		5、创建读写流 FileOutputStream 并管理文件位置。
//		6、记住 一个字节数组来存储,利用循环。
//		7、关闭所有流
		File [] files = dir.listFiles();
		Vector<FileInputStream> v = new Vector<FileInputStream>();
		for(int i = 1 ;i<files.length-1 ; i++){
			v.add(new FileInputStream("E:\\Test\\mp4\\"+i+".part"));
		}
		Enumeration<FileInputStream> en = v.elements();
		SequenceInputStream sis = new SequenceInputStream(en);
		FileOutputStream fos = new FileOutputStream("E:\\Test\\mp4\\008.mp4");
		int len = 0;
		byte [] by = new byte [1024];
		while((len = sis.read(by))!=-1){
			fos.write(by,0,len);
			fos.flush();
		}
		System.out.println("Sequence is Over!");
		fos.close();
		sis.close();
		
	}
}
//end
1、分割,读取文件的时候,
byte [] by = new byte[1024*1024*10]; 设置 10m  来设定 每一个分割文件的大小
2、合并,遍历 新增所有分割文件 到集合中  
sis = new SequenceInputStream(en) 接收集合转化的  枚举值  进行文件的合并。
3、删除文件时,注意判断 是否为文件夹  利用   递归    完成。



---------------------------------------------------------------------------------------------------------------------------------------------
---------- android培训、 java培训、期待与您交流!----------


----------------------------------------------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值