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

来源:互联网 发布:dekker算法 编辑:程序博客网 时间:2024/06/04 17:44

------- 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());//trueSystem.out.println(f1.createNewFile());//falseSystem.out.println(f1.delete());//trueSystem.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());//falseSystem.out.println(f2.isFile());//falseSystem.out.println(f2.isDirectory());//falseSystem.out.println(f2.isAbsolute());//falsetry {System.out.println(f2.createNewFile());//trueSystem.out.println(f2.isFile());//trueSystem.out.println(f2.isDirectory());//falseSystem.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.txtSystem.out.println(f1.getPath());//test.txtSystem.out.println(f1.getParent());//nullSystem.out.println(f1.getAbsolutePath());//D:\Code\Java\javaenhance\test.txtSystem.out.println(f1.lastModified());//1419651154909System.out.println(showDate(f1.lastModified()));//2014-32-27 11:32:34System.out.println(f1.length());//27File f2=new File("abc\\test.txt");//这个文件在硬盘上不存在System.out.println(f2.getName());//test.txtSystem.out.println(f2.getPath());//abc\test.txtSystem.out.println(f2.getParent());//abcSystem.out.println(f2.getAbsolutePath());//D:\Code\Java\javaenhance\abc\test.txtSystem.out.println(f2.lastModified());//0System.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);}}
运行结果:

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

利用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);}}}}








0 0