天天看点

黑马程序员_JAVA_IO(二)

------ Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

一、File类

文件和目录路径名的抽象表现形式

特点:

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

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

        3、File类的实例是不可变的;也就是说,一旦创建,File 对象表示的抽象路径名将永不改变

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

File对象创建方式:

       1、 File f =new File("a.txt");

       2、File f2=newFile("c:\\abc","b.txt");

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

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

File.separator表示目录分隔符,可以跨平台使用。相当于路径中的“\”。 

File类的常见方法:

1、创建

        booleancreateNewFile();

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

        boolean mkdir();//创建文件夹,只能创建一级文件夹

        boolean mkdirs();//创建多级文件夹

2、删除

        boolean delete();

        //删除文件或目录。文件存在,返回true;文件不存在或者正在被执行,返回false。    

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

3、判断

        boolean canExecute();//是否是可执行文件

        boolean exists();//文件是否存在

        boolean isFile();//是否是文件

        boolean isDirectory();//是否是文件夹

        boolean isHidden();//是否是隐藏文件

        boolean isAbsolute();//文件是否是绝对路径

在判断文件对象是否是文件或者目录时,必须要判断该文件对象封装的内容是否存在。

4、获取信息

        String getName();//获取文件名

        String getPath();//获取文件的相对路径(即创建的对象传入的参数是什么就获取到什么)

        String getParent();//获取文件父目录。返回的是绝对路径中的父目录。如果获取的是相对路径,返回null。如果相对路径中有上一层目录,那么该目录就是返回结果。

        String getAbsolutePath();//获取文件的绝对路径      

        long lastModified();//返回文件最后一次被修改的时间

        long length();//返回文件长度

renameTo(File f);重命名,还可以剪切文件。

5、列出文件及文件过滤

        static File[] listRoots();//列出可用的文件系统根目录,即系统盘符

        String[] list();//列出当前目录下所有文件,包括隐藏。调用list方法的file对象必须是封装了一个目录。该目录还必须存在。

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

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

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

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

import java.io.*;

class Demo {
	public static void main(String[] args) throws Exception {
		File dir = new File("d://");
		String[] arr = dir.list(new FilenameFilter() {
			public boolean accept(File dir, String name) {
				if (name.endsWith(".java"))
					return true;
				else
					return false;
			}
		});
		for (String s : arr) {
			System.out.println(s);
		}
	}
}
           

递归

       当函数内每一次循环还可以调用本功能来实现,也就是函数自身调用自身。这种表现形式,或者编程手法,称为递归。

递归注意事项

        1、限定条件。是来结束循环调用,否则是死循环。

        2、注意递归的次数,尽量避免内存溢出。因为每次调用自身的时候都会先执行下一次调用自己的方法,所以会不断在栈内存中开辟新空间,次数过多,会导致内存溢出。

示例一

//删除一个带内容的目录
import java.io.*;
class RemoveDir {
	public static void main(String[] args) {
		// 指定目录
		File dir = new File("e:\\1");
		// 删除目录
		removeDir(dir);
	}

	// 删除传入目录
	public static void removeDir(File dir) {
		File[] files = dir.listFiles();// 列出目录下的所以文件和文件夹
		// 遍历
		for (File file : files) {
			// 如果还是目录且非隐藏
			if (!file.isHidden() && file.isDirectory())
				removeDir(file);// 继续删除目录里的内容
			else
				System.out
						.println(file.toString() + ":-file-:" + file.delete());// 删除文件
		}
		System.out.println(dir + ":::dir:::" + dir.delete());// 删除目录
	}
}
           

示例二

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

class JavaFileList {
	public static void main(String[] args) {
		// 指定目录
		File dir = new File("e:/Java Study/Practice");

		// 定义一个List集合,用于存储.java文件的File对象
		List<File> list = new ArrayList<File>();

		// 调用获取文件路径方法
		fileToList(dir, list);

		// 指定写入文件
		File file = new File(dir, "javafilelist.txt");
		// 调用写入文件方法
		writeToFile(list, file);
	}

	// 获取指定文件夹内的所有java文件的绝对路径,并存入集合中
	public static void fileToList(File dir, List<File> list) {
		File[] files = dir.listFiles();// 列出dir路径下的所以文件和目录,
		// 遍历
		for (File file : files) {
			// 如果是目录,则继续获取
			if (file.isDirectory()) {
				list.add(file.getAbsoluteFile());// 把父目录路径也存入
				fileToList(file, list);
			}
			// 将是.java文件的绝对路径存入
			else if (file.getName().endsWith(".java"))
				list.add(file);
		}
	}

	// 将集合中元素写入到一个文本文件中
	public static void writeToFile(List<File> list, File file) {

		BufferedWriter bw = null;

		try { // 使用字符流缓冲区对象关联写入的文件
			bw = new BufferedWriter(new FileWriter(file));
			for (File file0 : list) {
				bw.write(file0.getAbsolutePath());// 写入
				bw.newLine();// 换行
				bw.flush();// 刷新
			}
		} catch (IOException e) {
			throw new RuntimeException("写入文件失败");
		} finally {
			try {
				if (bw != null)
					bw.close();// 关流
			} catch (IOException e) {
				throw new RuntimeException("流资源关闭失败");
			}
		}
	}
}
           

二、Properties类

Properties是Hashtable的子类,它具备Map集合的特点。而且它里面还有存储的键值对,都是字符串,无泛型定义。是集合中和IO技术想结合的集合容器。

特点:1、可用于键值对形式的配置文件

            2、在加载时,需要数据有固定的格式,常用的是:键=值

常用方法

        Object setProperty(String key,String value); //设置键和值,调用Hashtable的方法put

        String getProperty(String key);//指定key搜索value

        Set<String> stringPropertyName();//返回属性列表的键集,存入Set集合

        void load(InputStream ism); //从输入字节流中读取属性列表(键和元素对)。又称将流中的数据加载进集合。

        void load(Reader reader); //从输入字符流中读取属性列表(键和元素对)。又称将流中的数据加载进集合。

        void list(PrintStream out);//将属性列表输出到指定的输出流

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

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

public static void method() throws IOException {
		
	BufferedReader bufr = new BufferedReader(new FileReader("info.txt"));
	
	String line = null;
		
	Properties prop = new Properties();
		
	while((line=bufr.readLine()) != null) {
		String[] arr = line.split("=");
		prop.setProperty(arr[0], arr[1]);
	}
	bufr.close();
}
           

三、打印流(PrintWriter,PrintStream)

      该流提供了打印方法,可将各种类型的数据都原样打印。

字节打印流:PrintStream

可接收的参数类型:

        1、File对象。File

        2、字符串路径:String

        3、字符输出流:OutputStream

 字符串打印流:PrintWriter

可接受的参数类型

        1、File对象:File

        2、字符串路径:String

        3、字节输出流:OutputStream

        4、字符输出流:Writer

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);

		String line = null;

		while((line=bufr.readLine())!=null)
		{
			if("over".equals(line))//结束字符
				break;
			out.println(line.toUpperCase());
			//out.flush();
		}
		
		//关流
		out.close();
		bufr.close();

	}	
}
           

四、序列流(SequenceInputStream)

对多个流进行合并,也被称为合并流。常用构造函数SequenceInputStream(Enumeration<?extends FileInputStream> e)

// SequenceInputStream实例
import java.util.*;
import java.io.*;
class SequenceInputStreamDemo {
	public static void main(String[] args) throws IOException {
		// 创建vector集合,并添加相关流对象
		Vector<InputStream> ve = new Vector<InputStream>();
		ve.add(new FileInputStream("1.txt"));
		ve.add(new FileInputStream("2.txt"));
		ve.add(new FileInputStream("3.txt"));

		Enumeration<InputStream> en = ve.elements();// 创建枚举对象
		SequenceInputStream sis = new SequenceInputStream(en);// 合并流
		FileOutputStream fos = new FileOutputStream("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.util.*;
import java.io.*;
class SplitMergeFile {
	public static void main(String[] args) throws IOException {
		// 指定要切割的文件
		File file = new File("a.mp3");
		// 将指定文件进行切割
		splitFile(file);

		// 指定要合并到的文件
		File file1 = new File("b.mp3");
		// 将部分文件进行合并指定文件中
		merge(file1);

	}

	// 接收一个文件,将其按1M大小进行切割
	public static void splitFile(File file) throws IOException {
		// 关联要切割的文件
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
				file));

		BufferedOutputStream bos = null;

		// 定义1M大小存储容器
		byte[] buf = new byte[1024 * 1024];
		int len = 0, x = 0;
		while ((len = bis.read(buf)) != -1) {
			// 每满1M就写入一个新文件中
			bos = new BufferedOutputStream(new FileOutputStream("D:\\" + (++x)
					+ ".part"));
			bos.write(buf, 0, len);
			bos.close();// 没写完一个文件要记得关流
		}
		// 关流
		bis.close();
	}

	// 将部分文件合并为一个可执行文件
	public static void merge(File file) throws IOException {
		// 定义一个集合存储这些部分文件关联路径数据
		ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();

		for (int x = 1; x <= 6; x++) {
			al.add(new FileInputStream("D:\\" + x + ".part"));
		}

		// 因为Enumeration是Vector特有的迭代方法,所以这里创建一个Enumeration类型的匿名内部类
		final ListIterator<FileInputStream> it = al.listIterator();
		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(file);

		// 定义临时存储数据的数组
		byte[] buf = new byte[1024];
		int len = 0;
		while ((len = sis.read(buf)) != -1) {
			fos.write(buf, 0, len);// 写数据
		}
		fos.close();
		sis.close();
	}
}