黑马程序员——Java IO流 3——文件流

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

这里的文件流泛指一系列java.io包中操作文件的类的统称。

File概述

File类不仅能对文件进行封装还能对文件夹进行封装,这是字节流和字符流所不具有的功能。
下面举例说明File类的用法:
import java.io.File;

public class FileStream {
	public static void main(String[] args) {
		//File既可以将已存在的文件封装成对象,也可以将不存在的文件封装成对象
		File f1=new File("c:\\abc\\a.txt");
		//File类的构造函数既可以接受完整路径,也可以接受相对路径
		File f2=new File("a.txt");
		//File类还有一种构造方法,可以接收两个参数,一个是目录路径,一个是文件名
		File f3=new File("c:\\abc","c.txt");
		File f4=new File("c:\\abc");
		File f5=new File(f4,"c.txt");
		
		System.out.println(f1);
		System.out.println(f2);
		System.out.println(f3);
		System.out.println(f4);
		System.out.println(f5);
	}
}
上面的程序输出结果为:
c:\abc\a.txt
a.txt
c:\abc\c.txt
c:\abc
c:\abc\c.txt
上面的程序演示了3种创建File类的对象的方法,由程序结果可以发现,直接打印输出File类对象返回的是它所封装的路径。
File类还有一个静态字段File.separator,用于返回当前操作系统的文件路径分隔符。Windows是反斜杠(\),Linux是正斜杠(/)。由于反斜杠在java字符串里是转义字符,所以在字符串使用文件路径需要两个反斜杠来(\\)表示Windows路径分隔符。

File对象的功能——创建和删除

创建:createNewFile()方法,实例方法,返回值是boolean类型,true表示创建成功,false表示创建失败, 当相同目录下存在同名文件时,则会创建失败。这个和字节流字符流不一样。这个方法不会覆盖已存在的文件。注意创建File对象不会创建文件,只有调用了此方法才会真正创建文件。
   mkdir()方法: 实例方法,创建单级目录,返回值是boolean类型,true表示创建成功,false表示创建失败,  当相同目录下存在同名文件夹时,则会创建失败。
   mkdirs()方法: 实例方法,创建多级目录,返回值是boolean类型,true表示创建成功,false表示创建失败,  当相同目录下存在同名文件夹时,则会创建失败。
删除:delete()方法:实例方法,删除失败返回false。比如文件被其他程序占用,或者文件不存在。注意delete方法删除的文件不会进回收站
  deleteOnExit():实例方法,程序退出时删除,一般用于删除临时文件。
示例代码如下:
import java.io.File;
import java.io.IOException;

public class FileDemo {
	public static void main(String[] args) {
		File f1=new File("readme.txt");
		try {
			System.out.println(f1.createNewFile());//true
			System.out.println(f1.createNewFile());//false
			System.out.println(f1.delete());//true
			System.out.println(f1.delete());//false
		} catch (IOException e){
			e.printStackTrace();
		}	
	}
}

File对象功能——判断

判断:exists() :判断File对象封装的路径的文件或文件夹是否存在
  isFile():判断 File对象封装的路径是否是文件。注意,如果路径所指向的文件或文件不存在,则返回false。
  isDirectory():判断File对象封装的路径是否是文件夹。注意,如果路径所指向的文件夹不存在,则返回false。
  isAbsolute():判断File对象封装的路径是否是绝对路径,如果是绝对路径,即使指向的文件或文件夹不存在,也会返回true。绝对路径以物理磁盘盘符开头,例如C:\\a.txt
File f2=new File("hello.txt");
System.out.println(f2.exists());//false
System.out.println(f2.isFile());//false
System.out.println(f2.isDirectory());//false
System.out.println(f2.isAbsolute());//false
try {
	System.out.println(f2.createNewFile());//true
	System.out.println(f2.isFile());//true
	System.out.println(f2.isDirectory());//false
	System.out.println(f2.isAbsolute());//false
} catch (IOException e){
	e.printStackTrace();
}
注意hello.txt也有可能是文件夹,如下图所示

File对象功能——获取

getName();
getParent();//该方法返回的是绝对路径中的父目录
getAbsolutePath();
getPath();
lastModified();
length();
下面举例说明:
public static void method3(){
	File f1=new File("test.txt");//这个文件在硬盘上存在
	System.out.println(f1.getName());//test.txt
	System.out.println(f1.getPath());//test.txt
	System.out.println(f1.getParent());//null
	System.out.println(f1.getAbsolutePath());//D:\Code\Java\javaenhance\test.txt
	System.out.println(f1.lastModified());//1419651154909
	System.out.println(showDate(f1.lastModified()));//2014-32-27 11:32:34
	System.out.println(f1.length());//27
	File f2=new File("abc\\test.txt");//这个文件在硬盘上不存在
	System.out.println(f2.getName());//test.txt
	System.out.println(f2.getPath());//abc\test.txt
	System.out.println(f2.getParent());//abc
	System.out.println(f2.getAbsolutePath());//D:\Code\Java\javaenhance\abc\test.txt
	System.out.println(f2.lastModified());//0
	System.out.println(f2.length());//0
}
public static String showDate(long millisecond){
	Date date=new Date(millisecond);
	SimpleDateFormat simple=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	return simple.format(date);
}
上面代码中右边的注释是运行结果,之所以为静态是方便在java主函数中调用.
renameTo():剪切
举例:
public static void method7(){
	File f1=new File("c:\\Test.java");//文件存在
	File f2=new File("d:\\haha.java");//文件不存在
	System.out.println(f1.renameTo(f2));//返回剪切是否成功
}

File对象功能——文件列表

listRoots():列出所有硬盘盘符,举例如下:
	public static void method4(){
		
		File[] files=File.listRoots();
		for (File f : files) {
			System.out.println(f);
		}
	}
运行结果:

list()方法:列出指定目录下所有的文件和目录名称,包括隐藏文件和目录,举例如下:
	public static void method5(){
		File file=new File("F:\\");
		//调用list方法的File必须封装的是一个目录并且该目录在硬盘上存在,否则返回空指针异常
		String[] namesStrings=file.list();
		for (String name : namesStrings) {
			System.out.println(name);
		}
	}
运行结果:
黑马程序员——Java IO流 3——文件流_第1张图片

列出指定目录下所有内容和递归

利用File对象的方法列出指定目录下所有的目录名和文件名,代码如下:
	public static void main(String[] args) {
		showDir(new File("F:\\Mytreasure\\study\\java"));
	}
	public static void showDir(File dir){
		System.out.println(dir.getAbsolutePath());
		File[] files=dir.listFiles();
		for (File file : files) {
			if (file.isDirectory()) {
				showDir(file);
			}else {
				System.out.println(file.getAbsolutePath());
			}
		}
	}
注意上面的代码中使用了递归算法来遍历目录和目录中的目录。
递归算法要注意, 必须有结束条件,否则会使程序陷入死循环。 
下面以将十进制数据转换为二进制数据为例,来演示递归:
public class RecursionDemo {
	public static void main(String[] args) {
		toBin(44115);
	}
	public static void toBin(int decimal){
		if (decimal>0) {
			toBin(decimal/2);
			System.out.print(decimal%2);
		}
	}
}
再举一例,用代码计算公差为1,首项为n,尾项为1的等差数列
	public static void main(String[] args) {
		System.out.println(getSum(1000));
	}
	public static int getSum(int n){
		if (n==1) {
			return 1;
		}else {
			return getSum(n-1)+n;
		}
	}
上面的例子要注意,当给getSum函数传过大的数值参数时,可能造成内存溢出,所以递归算法要注意 递归次数不要太多

列出目录下所有内容__带层次

import java.io.File;

public class FileOther {
	public static void main(String[] args) {
		showDir(new File("F:\\Mytreasure\\study\\java"),0);
	}
	public static String getIndent(int level){
		StringBuffer sb=new StringBuffer();
		for (int i = 0; i < level; i++) {
			sb.append("|--");
		}
		return sb.toString();
	}
	public static void showDir(File dir,int level){
		System.out.println(getIndent(level)+dir.getAbsolutePath());
		level++;
		File[] files=dir.listFiles();
		for (File file : files) {
			if (file.isDirectory()) {
				showDir(file,level);
			}else {
				System.out.println(getIndent(level)+file.getAbsolutePath());
			}
		}
	}
}
主要就是加了个生成多级缩进的方法。

删除带内容的目录

public static void main(String[] args) {
		boolean a=deleteDir(new File("F:\\1"));
		if (a) {
			System.out.println("删除成功");
		}else {
			System.out.println("删除失败");
		}
	}
	/**
	 * 递归删除指定目录中的所有目录和文件
	 * @param dir 指定目录
	 * @return true为删除成功,false为删除失败
	 */
	public static boolean deleteDir(File dir){
		boolean isSuccess=true;
		File[] files=dir.listFiles();
		for (File file : files) {
			if (file.isDirectory()) {
				isSuccess=deleteDir(file);
				if (!isSuccess) {
					return false;
				}
			}else {
				isSuccess= file.delete();
				if (!isSuccess) {
					return false;
				}
			}
		}
		isSuccess=dir.delete();
		if (!isSuccess) {
			return false;
		}
		return true;
	}
上面的代码递归删除文件夹和其中的所有东西,注意递归层层传递返回值的技巧,这个是视频中没讲到的。

创建JAVA文件列表

编写一个程序,把指定目录下的所有java源文件的绝对路径保存到一个文本文件中。代码如下:
package File;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;

/**
 * 对指定目录建立一个java文件列表,并保存到文件中
 * 思路:
 * 1.递归遍历指定目录
 * 2.递归过程中获取该目录的所有Java文件的路径
 * 3.将路径保存到集合中
 * 4.把集合中的数据输出到文件中
 */
public class JavaFileList {
	public static void main(String[] args) {
		File dir=new File("F:\\Mytreasure\\study\\java\\3GetStarted");
		List<File> list=new ArrayList<File>();
		RecursionToGetPath(dir, list);
		File targetFile=new File("F:\\Mytreasure\\study\\java\\javaList.txt");
		listToFile(list,targetFile);
	}
	public static void RecursionToGetPath(File dir,List<File> list){
		File[] files=dir.listFiles();
		for (File file : files) {
			if (file.isDirectory()) {
				RecursionToGetPath(file, list);
			}else {
				if (file.getAbsolutePath().endsWith(".java")){
					list.add(file);
				}
			}
		}	
	}
	public static void listToFile(List<File> list,File targetFile){
		BufferedWriter bfwr=null;
		try {
			bfwr=new BufferedWriter(new FileWriter(targetFile));
			for (File file : list) {
				bfwr.write(file.toString());
				bfwr.newLine();
				bfwr.flush();
			}
		} catch (IOException e) {
			throw new RuntimeException(e);
		} finally {
			try {
				if (bfwr != null)
					bfwr.close();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
	}
}

Properties简述

Properties是hashtable的子类,Properties位于java.util包中,它具备map集合的特点,它里面存储的键值对都是字符串,它是集合技术和IO技术相结合的容器。Properties对象常用于处理键值对形式的配置文件,比如.ini文件。
setProperty(String key,String value):保存键值对或修改值。
getProperty(String key):根据键获取值。
stringPropertyNames():获取所有的键,jdk1.6新方法。
上面方法的演示如下:
package File;

import java.util.Properties;
import java.util.Set;

public class PropertiesDemo {
	public static void main(String[] args) {
		Properties prop=new Properties();
		//保存键值对
		prop.setProperty("张三", "24岁");
		prop.setProperty("李四", "20岁");
		System.out.println(prop);//{张三=24岁, 李四=20岁}
		//根据键获取值
		System.out.println(prop.getProperty("张三"));//24岁
		//根据键修改值
		prop.setProperty("李四", "40岁");
		System.out.println(prop.getProperty("李四"));//40岁
		//获取所有键
		Set<String> keys=prop.stringPropertyNames();
		for (String key : keys) {
			System.out.println(key+":"+prop.getProperty(key));
		}
	}
}
上面的代码输出:
{张三=24岁, 李四=20岁}
24岁
40岁
张三:24岁
李四:40岁

Properties存取配置文件

load(InputStream input)读取配置文件
store(OutputStream output,String comment)存到配置文件,第二个参数不能含中文,如果用此方法存储的配置含中文,则会把中文对应的Unicode编码存储到配置文件中。
示例代码如下
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;

public class PropertiesDemo {
	public static void main(String[] args) {
		saveAndLoad();
	}
	public static void saveAndLoad(){
		Properties prop=new Properties();
		prop.setProperty("jdk", "1.6");
		prop.setProperty("os", "windows 8");
		//将Properties对象的数据写入到文件中
		FileOutputStream fos=null;
		try {
			fos=new FileOutputStream("F:\\Mytreasure\\study\\java\\testData\\PropertyContent.ini");
			prop.store(fos, "create property file");
		} catch (IOException e) {
			throw new RuntimeException(e);
		} finally {
			try {
				if (fos != null)
					fos.close();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
		//通过Properties读取数据
		FileInputStream fis=null;
		try {
			fis=new FileInputStream("F:\\Mytreasure\\study\\java\\testData\\PropertyContent.ini");
			prop.load(fis);
			System.out.println(prop);
		} catch (IOException e) {
			throw new RuntimeException(e);
		} finally {
			try {
				if (fis != null)
					fis.close();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
		//通过Properties修改数据
		prop.setProperty("os", "window 10");
		//将Properties对象的数据写入到文件中
		try {
			fos=new FileOutputStream("F:\\Mytreasure\\study\\java\\testData\\PropertyContent.ini");
			prop.store(fos, "edit data");
		} catch (IOException e) {
			throw new RuntimeException(e);
		} finally {
			try {
				if (fos != null)
					fos.close();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
	}
}
练习:用配置文件存储程序运行次数,当运行5次后,提醒用户程序运行次数已到
	public static void calculate(){
		Properties prop=new Properties();
		File file=new File("F:\\Mytreasure\\study\\java\\testData\\count.ini");
		if (!file.exists()) {
			try {
				file.createNewFile();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}

		FileInputStream fis=null;
		FileOutputStream fos=null;
		try {
			fis=new FileInputStream(file);
			prop.load(fis);		
			String str=prop.getProperty("count");
			int count=0;
			if (str!= null) {
				count=Integer.parseInt(str);
				if (count>=5) {
					System.out.println("您的使用次数已到,请注册软件");
					return;
				}
			}
			count++;
			prop.setProperty("count", count+"");
			fos=new FileOutputStream(file);
			prop.store(fos, "");
		} catch (IOException e) {
			throw new RuntimeException(e);
		} finally {
			try {
				if (fis != null)
					fis.close();
				if (fos != null)
					fos.close();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}		
	}

PrintWriter

提供了打印方法,可以将各种数据类型原样打印。
字节打印流: PrintStream
构造函数可以接受的参数类型:
1.file对象。File
2.字符串路径。String
3.字节输出流。OutputStream
字符打印流: PrintWriter
构造函数可以接受的参数类型:
1.file对象。File。还有一个字符串参数 用来指定字符集
2.字符串路径。String
3.字节输出流。OutputStream。还有一个boolean参数用来指定是否自动刷新缓冲区。
4.字符输出流。Writer

下面举例说明PrintWriter的用法,下面的程序会从键盘读入录入的字符串,转换为大写后,输出到a.txt文件中:
import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;

public class PrintWriterDemo {
	public static void main(String[] args) {
		BufferedReader bufr=null;
		PrintWriter pw=null;
		try {
			bufr=new BufferedReader(new InputStreamReader(System.in));
			pw=new PrintWriter(new FileWriter("a.txt"),true);
			String line="";
			while((line=bufr.readLine())!=null){
				if("over".equals(line))
					break;
				pw.println(line.toUpperCase());
			}
		} catch (IOException e) {
			throw new RuntimeException(e);
		} finally {
			try {
				if (bufr != null)
					bufr.close();
				if (pw != null)
					pw.close();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
	}
}








你可能感兴趣的:(黑马程序员——Java IO流 3——文件流)