黑马程序员——IO流之File类、递归、Properties类

本文详细介绍了Java中File类与Properties类的使用方法,包括文件与目录的操作,以及如何通过Properties类进行配置文件的读取、修改和保存。通过实例演示了如何读取和修改配置文件,限制程序运行次数,实现应用程序数据的共享。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

一、File

1、概述

File类:文件和目录路径名的抽象表示形式。

作用:

用来将文件或者文件夹封装成对象 

方便对文件与文件夹的属性信息进行操作。

 File对象可以作为参数传递给流的构造函数。 

2、构造方法

将文件封装成File对象,可以将已有的和未出现的文件或者文件夹封装成对象。

具体方法:

   1、将相对路径下的文件a.txt封装成File对象,也可以封装绝对路径。

      File f1 = new File("a.txt");

   2、将 c:\abc\b.txt 文件封装成File对象

      File f2 = new File("c:\\abc","b.txt");

   3、将 c:\abc\b.txt 文件封装成File对象。

      File d = new File("c:\\abc");

      File f3 = new File(d,"c.txt");

   注意:以上构造方法中都是使用"\\"来代表windows中的分隔符"\",但在Linux等其他平台中不一定适用。可用File.separator替换"\\"来实现跨平台。如:

      File f4 = new File("c:"+File.separator+"abc"+File.separator+"zzz"+File.separator+"a.txt");

3、常见方法

1,创建。

      boolean createNewFile(): 在指定位置创建文件,如果该文件已经存在,则不创建,返回false。和输出流不一样,输出流对象一建立创建文件,而且文件已经存在,会覆盖。

      boolean mkdir(): 创建文件夹,只能创建一级。

      boolean mkdirs(): 创建多级文件夹。


2,删除。

      boolean delete(): 删除成功返回true 失败false。如果文件正在被使用等,则删除不了返回falsel。

      void deleteOnExit(); 在程序退出时删除指定文件。注意:一旦请求了删除操作,就无法取消该请求。


3,判断。

      boolean exists(): 判断文件是否存在.存在返回true

      boolean isFile(): 判断路径指定的目标是否为文件

      boolean isDirectory(); 判断路径指定的目标是否是一个目录(文件夹)。

      boolean isHidden(); 判断路径指定的目标是否是隐藏属性。

      boolean isAbsolute(); 判断路径是否为绝对路径


4,获取信息。

      String getName(): 获取文件名

      String getPath(): 获取文件的路径(与构造对象时候传入的参数一致)

      String getParent(): 获取文件的父目录。如果构造对象是没有指定文件的父目录,返回null


      String getAbsolutePath(): 获取文件的绝对路径,即使构造对象时指点的是相对路径。

      long lastModified(): 获取文件的最后一次修改时间。

      long length(): 获取文件的长度


5、列出文件列表

  static File[] listRoots();  列出可用的文件系统根目录(C:\    D:\    E:\    .....)。静态方法

   调用下面方法的对象的路径表示的不是一个目录,那么此方法将返回 null,此时遍历数据时会出错。

           String[] list();  列出当前目录下所有文件,包括隐藏的。

           String[] list(FilenameFilter filter);  返回一个字符串数组,获取目录中满足指定过滤器的文件或目录。

   大多数情况下会使用listFile方法,因为返回的是File对象,方便操作。

           File[] listFiles();  返回一个抽象路径名数组,获取当前文件夹下的所有文件和文件夹

           File[] listFiles(FilenameFilter filter);  返回抽象路径名数组,获取目录中满足指定过滤器的文件或目录。 

           FilenameFilter:文件名过滤器,是一个接口,其中包含一个方法,accept(Filedir,String name),返回的是boolean型,对不符合条件的文件过滤掉

例1:打印C盘中的隐藏文件

import java.io.*;

class FileList 
{
	public static void main(String[] args) 
	{
		//将"C:\\"封装成文件
		File file = new File("C:\\");

		//调用listFile()方法,过滤器为匿名内部类。获取到到File数组
		File[] files = file.listFiles(new FilenameFilter(){
			//这是一个实现了FilenameFilter接口的匿名内部类	
			public boolean accept(File dir,String name)
			{
				//dir是路径,name是文件名,用构造方法new File("c:\\abc","b.txt");
				//然后判断是否为隐藏文件
				return new File(dir,name).isHidden();
			}
		});

		//使用高级for循环,遍历结果
		for(File f : files)
		{
			System.out.println(f.getName());
		}
	}
}


二、递归

1、概述

函数自身调用自身,这种表现形式,或者编程手法,称为递归。

递归要注意:

1,限定条件。(没有限定条件无法停止,类似死循环)

2,要注意递归的次数。尽量避免内存溢出。(在限定条件达成前,会一直调用函数,不断占用内存)

例2:通过递归求和。

public static int getSum(int n)
{
	if(n==1)//限定条件,
		return 1;
	return n+getSum(n-1);
}

该方法如果传入的参数过大,容易造成内存溢出。

2、应用举例

例3:通过递归打印目录中所有文件,包括所有子目录

/*
列出指定目录下文件或者文件夹,包含子目录中的内容。
也就是列出指定目录下所有内容。

因为目录中还有目录,只要使用同一个列出目录功能的函数完成即可。
在列出过程中出现的还是目录的话,还可以再次调用本功能。
*/

import java.io.*;

class FileDemo3 
{
	public static void main(String[] args) 
	{
		File dir = new File("D:\\pp");
		showDir(dir);
	}

	public static void showDir(File dir)
	{
		System.out.println("--"+dir.getName());

		//首先先获取目录下的所有文件
		File[] files = dir.listFiles();

		for(int x=0; x<files.length; x++)
		{
			//如果指定文件是目录就调用自身方法进去打印
			//否则就直接打印。里面包含限定条件
			if(files[x].isDirectory())
			{
				showDir(files[x]);
			}
			else
				System.out.println(files[x].getName());
		}
	}
}


例4:删除带有内容的目录

/*
删除一个带内容的目录。
删除原理:
在window中,删除目录从里面往外删除的。

既然是从里往外删除。就需要用到递归。
*/
import java.io.*;
class  RemoveDir
{
	public static void main(String[] args) 
	{		
		File dir = new File("d:\\testdir");
		removeDir(dir);
	}

	public static void removeDir(File dir)
	{
		File[] files = dir.listFiles();
		
		for(int x=0; x<files.length; x++)
		{
			if(files[x].isDirectory())
				removeDir(files[x]);
			else
				System.out.println(files[x].toString()+":-file-:"+files[x].delete());
		}
		System.out.println(dir+"::dir::"+dir.delete());
	}
}

例5:建立一个java文件列表文件。

/*
将一个指定目录下的java文件的绝对路径,存储到一个文本文件中。
建立一个java文件列表文件。

思路:
1,对指定的目录进行递归。
2,获取递归过程所以的java文件的路径。
3,将这些路径存储到集合中。
4,将集合中的数据写入到一个文件中。
*/
import java.io.*;
import java.util.*;
class  JavaFileList
{
	public static void main(String[] args) throws IOException
	{		
		File dir = new File("d:\\java1223");

		List<File> list = new ArrayList<File>();

		fileToList(dir,list);

		File file = new File(dir,"javalist.txt");
		writeToFile(list,file.toString());
	}

	public static void fileToList(File dir,List<File> list)
	{
		File[] files = dir.listFiles();

		for(File file : files)
		{
			if(file.isDirectory())
				fileToList(file,list);
			else
			{
				if(file.getName().endsWith(".java"))
					list.add(file);
			}
		}
	}

	public static void writeToFile(List<File> list,String javaListFile)throws IOException
	{
		BufferedWriter bufw =  null;
		try
		{
			bufw = new BufferedWriter(new FileWriter(javaListFile));
			
			for(File f : list)
			{
				String path = f.getAbsolutePath();
				bufw.write(path);
				bufw.newLine();
				bufw.flush();
			}
		}
		catch (IOException e)
		{
			throw e;
		}
		finally
		{
			try
			{
				if(bufw!=null)
					bufw.close();
			}
			catch (IOException e)
			{
				throw e;
			}
		}
	}
}

三、Properties

1、概述

Properties是hashtable的子类,也就是说具备map集合的特点。而且它里面存储的键值对都是字符串,无需定义泛型。是集合中和IO技术相结合的集合容器。

该对象的特点:可以用于键值对形式的配置文件。

加载数据时,需要数据有固定格式:键=值。


2、常用方法

1、设置

        Object setProperty(String key,String value);       将键值添加进集合中,如添加的键相同则会覆盖原有的值。

2、获取

        String getProperty(String key);        根据提供的 键 获取相应的 值 。

        Set<String> stringPropertyName();        返回包含所有 键 的Set集合,可根据该Set集合遍历Properties集合

3、加载流和存入流

        void load(InputStream inStream);        从输入字节流中读取属性(键值对)并添加进集合中。固定格式:键=值

        void load(Reader reader);       从输入字符流中读取属性(键值对)并添加进集合中。固定格式:键=值

        void list(PrintStream out);       将Properties集合输出到指定的输出流,如:System.out

        void store(OutputStream  out,String comments);        对应load(InputStream)将属性Properties集合(键值对)写入输出流。comments属性列表的描述。

        void store(Writer  writer, String comments);        对应load(Reader)将Properties集合(键值对)写入输出流。comments属性列表的描述。

例6:读取一个配置文件,修改其中的一项,并保存和打印。

//读取一个配置文件,修改其中的一项,并保存和打印。
import java.io.*;
import java.util.*;

class PropertiesDemo 
{
	public static void main(String[] args)
	{
		FileInputStream fis = null;
		FileOutputStream fos = null;
		try
		{
			fis = new FileInputStream("info.txt");
			fos = new FileOutputStream("info_new.txt");

			Properties prop = new Properties();

			//将流中的数据加载进Properties集合。
			prop.load(fis);

			//将Properties集合中的一项"wangwu",修改为"39"
			prop.setProperty("wangwu","39");		
			
			//将Properties集合中的信息通过流保存,并添加标注信息(标注中无法正常显示中文)
			prop.store(fos,"BiaoZhu");
			//通过System.out 输出 Properties集合
			prop.list(System.out);
		}
		catch (IOException e)
		{
			throw new RuntimeException("读写文件失败");
		}
		//finall里面为关闭流的代码
		finally
		{
			try
			{
				if (fos!=null)
					fos.close();
			}
			catch (IOException e)
			{
				throw new RuntimeException("输出流关闭失败");
			}			
			try
			{
				if (fos!=null)
					fos.close();
			}
			catch (IOException e)
			{
				throw new RuntimeException("输入流关闭失败");
			}			
		}
	}
}

程序的运行结果:


例7:案例:限制程序运行次数。当运行次数到达5次时,给出,请您注册的提示。并不再让该程序执行。

/*
用于记录应用程序运行次数。
如果使用次数已到,那么给出注册提示。

很容易想到的是:计数器。
可是该计数器定义在程序中,随着程序的运行而在内存中存在,并进行自增。
可是随着该应用程序的退出,该计数器也在内存中消失了。

下一次在启动该程序,又重新开始从0计数。
这样不是我们想要的。

程序即使结束,该计数器的值也存在。
下次程序启动在会先加载该计数器的值并加1后在重新存储起来。

所以要建立一个配置文件。用于记录该软件的使用次数。

该配置文件使用键值对的形式。
这样便于阅读数据,并操作数据。

键值对数据是map集合。
数据是以文件形式存储,使用io技术。
那么map+io -->properties.

配置文件可以实现应用程序数据的共享。
*/
import java.io.*;
import java.util.*;

class  RunCount
{
	public static void main(String[] args) throws IOException
	{
		Properties prop = new Properties();

		//先创建File对象,可先判断文件是否存在,避免流在读取时文件出错
		File file = new File("count.ini");
		//如果文件不存在,则创建。
		if(!file.exists())
			file.createNewFile();
		
		FileInputStream fis = new FileInputStream(file);

		//将文件加载进Properties集合中。
		prop.load(fis);
		

		int count = 0;
		//获取Properties集合中计算次数"time"键中的 值 。
		String value = prop.getProperty("time");
		
		//判断value是否为空,如果不为空则判断是否已经达到了免费使用的次数。
		if(value!=null)
		{
			count = Integer.parseInt(value);
			if(count>=5)
			{
				System.out.println("您好,使用次数已到,拿钱!");
				return ;
			}
		}
		
		//执行到这里则表示符合免费使用。将使用次数增加一次
		count++;
		prop.setProperty("time",count+"");

		//通过流存到文件中
		FileOutputStream fos = new FileOutputStream(file);
		prop.store(fos,"");

		fos.close();
		fis.close();
		
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值