黑马程序员__JAVA基础__IO流(三)

------------android培训java培训、java学习型技术博客、期待与您交流! ------------

1.File类

    File类是文件和目录路径名的抽象表示形式。 是io包中唯一代表磁盘文件本身的对象,其定义了一些与平台无关的方法来操作文件,可以通过调用File类中的方法,实现创建.删除.重命名文件等操作,File类是对象主要用来获取未文件本身的一些信息,如文件所在的目录、文件的长度、文件的读写权限等。File对象可以作为参数传递给流的构造函数

    构造方法:

    |--->File(File parent, String child) 
            根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。 
    |--->File(String pathname) 
            通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。 
    |--->File(String parent, String child) 
            根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。 
    |--->File(URI uri) 
            通过将给定的 file: URI 转换为一个抽象路径名来创建一个新的 File 实例。 

    常见方法:

    1.创建

        boolean createNewFile():在指定位置创建文件,如果该文件已经存在,则不创建,返回false。
        boolean mkdir():创建文件夹。
        boolean mkdirs():创建多级文件夹。

        注:File类创建文件的方法createNewFile()与输出流的方法不同点:
            File类通过createNewFile方法来创建文件的话,如果文件存在则不创建
            输出流是对象一建立就创建文件,如果文件存在就会覆盖原文件。

    2.删除

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

        void deleteOnExit():在程序退出时删除指定文件。

    3.判断
        booleanexists():文件或目录是否存在。
        boolean isFile():是否是一个标准文件。
        boolean isDirectory():是否是一个目录。
        boolean isHidden():是否是一个隐藏文件。
        boolean isAbsolute():是否为绝对路径名。

        boolean canRead()是否可读
        boolean canWrite()是否可写

    4.获取

        String getName():返回由此抽象路径名表示的文件或目录的名称。
        String getPath():获取相对路径
        String getParent():获取父级目录,如果此路径名没有指定父目录,则返回 null。
        String getAbsolutePath():获取绝对路径
        long lastModified():返回此抽象路径名表示的文件最后一次被修改的时间。
        long length():返回由此抽象路径名表示的文件的长度.
        static File[] listRoots():列出系统的可用的根
        String[] list():获取指定目录下的所有文件和文件夹的名称数组
        File[] listFiles():获取指定目录下的所有文件和文件夹的File数组

    5.修改

        boolean renameTo(File dest):重新命名此抽象路径名表示的文件。

class FileDemo 
{
	public static void main(String[] args) throws IOException
	{
		method_5();
	}

	//renameTo()方法,相当于剪切
	public static void method_5()
	{
		File f1 = new File("c:\\Test.java");
		File f2 = new File("d:\\hahah.java");

		sop("rename:"+f2.renameTo(f1));

	}
	
	//获取各种路径
	public static void method_4()
	{
		File f = new File("file.txt");

		sop("path:"+f.getPath());
		sop("abspath:"+f.getAbsolutePath());
		sop("parent:"+f.getParent());//该方法返回的是绝对路径中的父目录。如果获取的是相对路径,返回null。
									//如果相对路径中有上一层目录那么该目录就是返回结果。

	}
	
	//创建文件,判断文件,以及查询文件
	public static void method_3()throws IOException
	{
		File f = new File("d:\\java1223\\day20\\file2.txt");

		f.createNewFile();

		f.mkdir();//创建此抽象路径名指定的目录


		//记住在判断文件对象是否是文件或者目的时,必须要先判断该文件对象封装的内容是否存在。
		//通过exists判断。
		sop("dir:"+f.isDirectory());
		sop("file:"+f.isFile());

		sop(f.isAbsolute());
	}

	public static void method_2()
	{
		File f = new File("file.txt");

		sop("exists:"+f.exists());//判断是否存在

		//测试应用程序是否可以执行此抽象路径名表示的文件。
		sop("execute:"+f.canExecute());

		//创建多级文件夹
		File dir = new File("abc\\kkk\\a\\a\\dd\\ee\\qq\\aaa");

		sop("mkdir:"+dir.mkdirs());
	}
	//删除相关文件
	public static void method_1()throws IOException
	{
		File f = new File("file.txt");
		sop("create:"+f.createNewFile());
		sop("delete:"+f.delete());
	}
	//创建File对象
	public static void consMethod()
	{
		//将a.txt封装成file对象。可以将已有的和未出现的文件或者文件夹封装成对象。
		File f1 = new File("c:\\abc\\a.txt");
		File f2 = new File("c:\\abc","b.txt");
		File d = new File("c:\\abc");
		File f3 = new File(d,"c.txt");

		sop("f1:"+f1);//打印结果c:\\abc\\a.txt
		sop("f2:"+f2);//打印结果c:\\abc\\b.txt
		sop("f3:"+f3);//打印结果c:\\abc\\c.txt

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

	}
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}


2.递归

    递归就是函数自己调用自己

    使用注意:

    1.在使用递归时,一定要明确递归的结束条件

    2.要注意递归的次数。尽量避免内存溢出

    应用场景:当某一功能要重复使用时

递归练习1:使用递归列出指定目录下所有内容

import java.io.*;
class FileDemo
{
	public static void main(String[] args)
	{
		File f=new File("d:\\java0410");//创建File对象,定义一个路径
		showDir(f);//往函数中传递一个路径dir
	}
	public static void showDir(File dir)
	{
		File[] files=dir.listFiles();//调用listFiles()方法.每个数组元素对应目录中的每个文件或目录
		int num=0;//定义一个变量
		for(File f:files)//使用高级for遍历
		{  
			if(files[num].isDirectory())//对元素进行判断是否是文件夹.如果是使用递归.
			showDir(files[num]);//递归自己调用自己
			System.out.println(files[num++]);
		}
	}
}

递归练习2:使用递归删除指定目录下所有文件

importjava.io.*;
class RemoveDir
{
	public static void main(String[]args)
	{
		Filedir=newFile("d:\\testdir");//创建File对象,定义一个路径
		removeDir(dir);//往函数中传递一个路径dir
	}
	public static void removeDir(Filedir)
	{
		File[] files=dir.listFiles();//调用listFiles()方法.每个数组元素对应目录中的每个文件或目录

		for(intx=0;x<files.length;x++)//遍历File数组
		{
			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());//删除完文件,删除文件夹
	}
}

递归练习3:使用递归算出指定数字范围内的整数之和

importjava.io.*;
class Add
{
	public static void main(String[] args)
	{
		System.out.println(Accum(0, 100));
	}
	
	public static int Accum(int m, int n)
	{
		//对于接受的参数,要考虑m >n,m=n,m<n三种情况。
		if (m < n)
		{
			return (m + Accum(++m, n)); //如果m<n,返回“m”加上“m+1到n累加的和”
		}
		else
		{
			if (m > n)
			{
				return (m + Accum(--m, n)); //如果m.n,返回“m”加上“m-1到n累加的和”
			}
			else
			{
				return n; //如果m=n,直接返回n,这是递归的关键。
			}
		}
	}
}

3.Properties类

    Properties是hashtable的子类,也就是说它具备map集合的特点。而且它里面存储的键值对都是字符串。
    是集合中和IO技术相结合的集合容器。
    该对象的特点:可以用于键值对形式的配置文件,那么在加载数据时,需要数据有固定格式:键=值。

    构造方法:

    |--->Properties():创建一个无默认值的空属性列表。 
    |--->Properties(Properties defaults):创建一个带有指定默认值的空属性列表。 

    常用方法:

    |--->Object setProperty(String key,String value)
            调用Hashtable的put方法,设置键值对
    |--->String getProperty(String key)

            用指定的键在此属性列表中搜索属性
    |--->Set<String> stringPropertyNames
            获取集合中所有的键
    |--->void load(InputStream in)
            从输入流中读取属性列表(键和元素对)。
    |--->void load(Reader reader)
            按简单的面向行的格式从输入字符流中读取属性列表(键和元素对)。
    |--->void list(PrintStream out)  
            将属性列表输出到指定的输出流。
    |--->void list(PrintWriter out)   
            将属性列表输出到指定的输出流。
    |--->void Store(OutputStream out,String comments)

            以适合使用 load(InputStream) 方法加载到 Properties 表中的格式,将此 Properties 表中的属性列表(键和元素对)写入输出流。 
    |--->void store(Writer writer, String comments) 
            以适合使用 load(Reader) 方法的格式,将此 Properties 表中的属性列表(键和元素对)写入输出字符。 

import java.io.*;
import java.util.*;

class PropertiesDemo 
{
	public static void main(String[] args) throws IOException
	{
		loadDemo();
	}
	public static void loadDemo()throws IOException
	{
		Properties prop = new Properties();
		FileInputStream fis = new FileInputStream("info.txt");

		//将流中的数据加载进集合。
		prop.load(fis);
		prop.setProperty("wangwu","39");//并没有写入到硬盘中,只写入到流中

		FileOutputStream fos = new FileOutputStream("info.txt");
		prop.store(fos,"haha");//将流中的数据写入到硬盘中
		prop.list(System.out);//列出目录

		fos.close();
		fis.close();
	}
	//设置和获取元素。
	public static void setAndGet()
	{
		Properties prop = new Properties();
		prop.setProperty("zhangsan","30");//设置元素
		prop.setProperty("lisi","39");

		String value = prop.getProperty("lisi");
		System.out.println(value);//打印出39
			
		prop.setProperty("lisi",89+"");

		Set<String> names = prop.stringPropertyNames();
		for(String s : names)
		{
			System.out.println(s+":"+prop.getProperty(s));
		}
	}
}
练习:限制程序运行次数。当运行次数到达5次时,给出相应提示。并不再让该程序执行

import java.io.*;
import java.util.*;
class  RunCount
{
	public static void main(String[] args) throws IOException
	{
		Properties prop = new Properties();

		File file = new File("count.ini");
		if(!file.exists())//如果不存在则创建配置文件
			file.createNewFile();
		FileInputStream fis = new FileInputStream(file);
		prop.load(fis);
		int count = 0;
		String value = prop.getProperty("time");//取出值
		
		if(value!=null)
		{
			count = Integer.parseInt(value);//转成int类型进行判断
			if(count>=5)
			{
				System.out.println("您好,使用次数已到,拿钱!");
				return ;
			}

		}
		count++;//使用一次则记录一次
		prop.setProperty("time",count+"");
		FileOutputStream fos = new FileOutputStream(file);
		prop.store(fos,"");//存入配置文件

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

4.打印流

    可以直接操作输入流和文件,该流提供了打印方法,可以将各种数据类型的数据都原样打印。

    字节打印流:PrintStream
        构造函数可以接收的参数类型:
        1.file对象:File
        2.字符串路径:String
        3.字节输出流:OutputStream

    字符打印流:PrintWriter
        构造函数可以接收的参数类型:
        1.file对象:File
        2.字符串路径:String
        3.字节输出流:OutputStream
        4.字符输出流:Writer

    注:与其他输出流不同,PrintStream 永远不会抛出IOException,而且打印流可以根据指定编码转成字符!

import java.io.*;

class  PrintStreamDemo
{
	public static void main(String[] args) throws IOException
	{
		BufferedReader bufr = 
			new BufferedReader(new InputStreamReader(System.in));//读取键盘输入

		PrintWriter out = new PrintWriter(new FileWriter("a.txt"),true);//ture代表自动刷新

		String line = null;

		while((line=bufr.readLine())!=null)
		{
			if("over".equals(line))
				break;
			out.println(line.toUpperCase());//转换成大写
			//out.flush();//刷新
		}
		out.close();
		bufr.close();
	}	
}

5.序列流

    SequenceInputStream是能对多个流进行合并成一个读取流,它在构造时需要传入Enumeration,而这个只用Vector中有,所以这个多个读取流要加入Vector集合中。
    注意:它只是对读取流进行合并。所以此对象没有对应的OutputStream

    使用步骤:
    1.创建Vector<InputStream>
    2.将要合并的InputStream加入Vector
    3.通过Vector获取Enumeration
    4.创建SequenceInputStream对象,将Enumeration作为参数传入。

代码示例:

import java.io.*;
import java.util.*;
class SequenceDemo 
{
	public static void main(String[] args) throws IOException
	{
		//创建Vector集合
		Vector<FileInputStream> v = new Vector<FileInputStream>();
		//将要合并的InputStream加入Vector
		v.add(new FileInputStream("c:\\1.txt"));
		v.add(new FileInputStream("c:\\2.txt"));
		v.add(new FileInputStream("c:\\3.txt"));

		//通过Vector获取Enumeration
		Enumeration<FileInputStream> en = v.elements();
		创建SequenceInputStream对象
		SequenceInputStream sis = new SequenceInputStream(en);

		//定义输出流
		FileOutputStream fos = new FileOutputStream("c:\\4.txt");
		byte[] buf = new byte[1024];
		int len =0;
		while((len=sis.read(buf))!=-1)
		{
			fos.write(buf,0,len);
		}

		fos.close();
		sis.close();

	}
}
练习:分割文件,并使用序列流将文件合并

import java.io.*;
import java.util.*;

class SplitFile 
{
	public static void main(String[] args) throws IOException
	{
		//splitFile();
		merge();
	}

	public static void merge()throws IOException
	{
		//Vector效率低,可以改用ArrayList  
		ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
		for(int x=1; x<=3; x++)
		{
			al.add(new FileInputStream("c:\\"+x+".part"));
		}


		//因为it要被Enumeration的匿名内部类对象使用,所以要加final  
		final Iterator<FileInputStream> it = al.iterator();

		//定义Enumeration子类对象进行,使用ArrayList的迭代器复写其方法,其实与ArrayList关联  
		Enumeration<FileInputStream> en = new Enumeration<FileInputStream>()
		{
			//复写方法
			public boolean hasMoreElements()
			{
				return it.hasNext();
			}
			public FileInputStream nextElement()
			{
				return it.next();
			}
		};

		//定义序列流对象,合并分割后的文件关联的流对象   
		SequenceInputStream sis = new SequenceInputStream(en);

		FileOutputStream fos = new FileOutputStream("c:\\合并.bmp");
		byte[] buf = new byte[1024];
		int len = 0;
		while((len=sis.read(buf))!=-1)
		{
			fos.write(buf,0,len);
		}
		fos.close();
		sis.close();
	}

	//分割文件
	public static void splitFile()throws IOException
	{
		FileInputStream fis =  new FileInputStream("c:\\分割.bmp");

		FileOutputStream fos = null;

		//定义分割文件大小
		byte[] buf = new byte[1024*1024];
		int len = 0;
		int count = 1;
		while((len=fis.read(buf))!=-1)
		{
			fos = new FileOutputStream("c:\\"+(count++)+".part");//新建流对象
			fos.write(buf,0,len);//写入
			fos.close();//关闭流
		}
		fis.close();//关闭读取流
	}
}

个人总结

    本节学习了File类,代表文件的本身,个人觉得里面有一个renameTo()方法可以看作文件剪切,调用非常方便。本节还要掌握一个函数的用法,递归,最要明确的就是递归的结束条件。IO中其他流对象在遇到不同的情况时根据需求选择流对象,这些都需要进行记忆的,只要明确在操作中有什么需求,就能引出具体的流对象。本节中有一个集合和IO技术相结合的集合容器,Properties类,属于hashtable的子类。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值