黑马程序员------IO(四)
1.1 File类
用来将文件或者文件夹封装成对象,方便对文件与文件夹的属性信息进行操作。
File对象可以作为参数传递给流的构造函数
1.1.2常见方法:
1,创建。
boolean createNewFile():在指定位置创建文件,如果该文件已经存在,则不创建,返回false。
和输出流不一样,输出流对象一建立创建文件。而且文件已经存在,会覆盖。
boolean mkdir():创建文件夹。
boolean mkdirs():创建多级文件夹。
static File createTempFile(String prefix, String suffix, File directory):
在指定目录中创建一个新的临时空文件,使用给定的前缀和后缀字符串生成其名称。
2,删除。
boolean delete():删除失败返回false。如果文件正在被使用,则删除不了返回falsel。
void deleteOnExit();在程序退出时删除指定文件。
3,判断。
boolean exists() :文件是否存在.
boolean canExecute():测试应用程序是否可以执行此抽象路径名表示的文件
isFile():
isDirectory();
isHidden();//判断文件是否隐藏
isAbsolute();
4,获取信息。
getName()://返回由此抽象路径名表示的文件或目录的名称。
getPath()://将此抽象路径名转换为一个路径名字符串。
getParent()://返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回 null。
getAbsolutePath() //返回此抽象路径名的绝对路径名字符串
long lastModified() // 返回此抽象路径名表示的文件最后一次被修改的时间,用于判断文件是否卑操作过
long length() //返回由此抽象路径名表示的文件的长度。
1 class FileDemo
2 {
3 public static void main(String[] args) throws IOException
4 {
5 method_5();
6 }
7
8 public static void method_5()
9 {
10 File f1 = new File("c:\\Test.java");
11 File f2 = new File("d:\\hahah.java");
12
13 sop("rename:"+f2.renameTo(f1));// ,如果盘符相同,则重新命名此抽象路径名表示的文件,如果盘符不同,则是重命名并移动文件。
14
15 }
16
17 public static void method_4()
18 {
19 File f = new File("file.txt");
20
21 sop("path:"+f.getPath());//获取路径,你封装的是什么路径我返回的就是什么路径
22 sop("abspath:"+f.getAbsolutePath());//获取绝对路径,无论你封装的是相对的还是绝对的,返回的都是绝对的,绝对路径其实就是把这个文件的所在的父目录加进来
23 sop("parent:"+f.getParent());//该方法返回的是绝对路径中的父目录。如果获取的是相对路径,返回null。
24 //如果相对路径中有上一层目录那么该目录就是返回结果。
25
26
27
28 }
29
30 public static void method_3()throws IOException
31 {
32 File f = new File("d:\\java1223\\day20\\file2.txt");
33
34 //f.createNewFile();
35
36 //f.mkdir();
37
38
39 //记住在判断文件对象是否是文件或者目的时,必须要先判断该文件对象封装的内容是否存在。
40 //通过exists判断。
41 sop("dir:"+f.isDirectory());-->//把f.mkdir()打开的话就是true
42 sop("file:"+f.isFile());-->false
43
44 sop(f.isAbsolute());//判断是否是绝对路径-->true
45 }
46
47
48 public static void method_2()
49 {
50 File f = new File("file.txt");
51
52 //sop("exists:"+f.exists());//判断文件是否存在
53
54 //sop("execute:"+f.canExecute());//判断文件是否可执行
55
56 //创建文件夹
57 File dir = new File("abc\\kkk\\a\\a\\dd\\ee\\qq\\aaa");
58
59 sop("mkdir:"+dir.mkdir());--->false,因为mkdir只能创建一级目录,即abc\\kkk
60 sop("mkdir:"+dir.mkdirs());--->true,mkdirs可创建多级目录
61 }
62
63
64 public static void method_1()throws IOException
65 {
66 File f = new File("file.txt");
67 f.deleteOnExit();//程序退出的时候删除文件
68 // sop("create:"+f.createNewFile());
69 //sop("delete:"+f.delete());
70
71
72
73
74 }
75
76
77
78
79
80
81
82 //创建File对象
83 public static void consMethod()
84 {
85 //将a.txt封装成file对象。可以将已有的和为出现的文件或者文件夹封装成对象。
86 File f1 = new File("a.txt");
87
88 //
89 File f2 = new File("c:\\abc","b.txt");
90
91
92 File d = new File("c:\\abc");
93 File f3 = new File(d,"c.txt");
94
95 sop("f1:"+f1);
96 sop("f2:"+f2);
97 sop("f3:"+f3);
98
99 File f4 = new File("c:"+File.separator+"abc"+File.separator+"zzz"+File.separator+"a.txt");//跨 平台系统目录分隔符,这句话可以实现跨平台,
100
101
102 }
103
104 public static void sop(Object obj)
105 {
106 System.out.println(obj);
107 }
108 }
1.2 递归:
函数自身直接或者间接的调用到了自身。
一个功能在被重复使用,并每次使用时,参与运算的结果和上一次调用有关。这时可以用递归来解决问题
1.2.2递归例子及原理图
例子1:
1 public static int getSum(int n)
2 {
3 if(n==1)
4 return 1;
5 return n+getSum(n-1);
原理图1:
例子2:
1 public static void toBin(int num)
2 {
3 if(num>0)
4 {
5 toBin(num/2);
6 System.out.println(num%2);
7 }
8 }
原理图2:
1.2.3递归注意事项:
1,限定条件。
2,要注意递归的次数。尽量避免内存溢出。
需求:
列出指定目录下文件或者文件夹,包含子目录中的内容。
也就是列出指定目录下所有内容。
分析:
因为目录中还有目录,只要使用同一个列出目录功能的函数完成即可。
在列出过程中出现的还是目录的话,还可以再次调用本功能。
也就是函数自身调用自身。
这种表现形式,或者编程手法,称为递归。
1 import java.io.*;
2
3 class FileDemo3
4 {
5 public static void main(String[] args)
6 {
7 File dir = new File("d:\\testdir");
8 //showDir(dir,0);
9
10 //toBin(6);
11 //int n = getSum(8000);--->异常,内存溢出
12 //System.out.println("n="+n);
13
14 System.out.println(dir.delete());
15 }
16 public static String getLevel(int level)
17 {
18 StringBuilder sb = new StringBuilder();
19 sb.append("|--");
20 for(int x=0; x<level; x++)
21 {
22 //sb.append("|--");
23 sb.insert(0,"| ");
24
25 }
26 return sb.toString();
27 }
28 public static void showDir(File dir,int level)
29 {
30
31 System.out.println(getLevel(level)+dir.getName());
32
33 level++;
34 File[] files = dir.listFiles();
35 for(int x=0; x<files.length; x++)
36 {
37 if(files[x].isDirectory())
38 showDir(files[x],level);
39 else
40 System.out.println(getLevel(level)+files[x]);
41 }
42 }
43
44 }
1.3Properties集合
Map
|--Hashtable
|--Properties
Properties是hashtable的子类。
也就是说它具备map集合的特点。而且它里面存储的键值对都是字符串。
是集合中和IO技术相结合的集合容器。
该对象的特点:可以用于键值对形式的配置文件。
那么在加载数据时,需要数据有固定格式:键=值。
1.3.1 练习:限制程序运行次数。当运行次数到达5次时,给出,请您注册的提示。并不再让该程序执行
1 import java.io.*;
2 import java.util.*;
3
4 class PropertiesDemo
5 {
6 public static void main(String[] args) throws IOException
7 {
8 //method_1();
9 loadDemo();
10 }
11
12 public static void loadDemo()throws IOException
13 {
14 Properties prop = new Properties();
15 FileInputStream fis = new FileInputStream("info.txt");
16
17 //将流中的数据加载进集合。
18 prop.load(fis);//即load(InputStream inStream)//从输入流中读取属性列表(键和元素对)。
19
20 prop.setProperty("wangwu","39");//这个setProperty方法改变的是内存的结果
21
22 FileOutputStream fos = new FileOutputStream("info.txt");
23
24 prop.store(fos,"haha");//store方法是讲内存的结果存到一个流当中并存到一个文件当中,store(Writer writer,String comments) ,writer - 输出字符流 writer。comments - 属性列表的描述(注释信息,你爱加不加)
25
26 // System.out.println(prop);
27 prop.list(System.out);//即list(PrintStream out)将属性列表输出到指定的输出流。
28
29 fos.close();
30 fis.close();
31
32 }
33
34 //演示,如何将流中的数据存储到集合中。
35 //想要将info.txt中键值数据存到集合中进行操作。
36 /*
37 1,用一个流和info.txt文件关联。
38 2,读取一行数据,将该行数据用"="进行切割。
39 3,等号左边作为键,右边作为值。存入到Properties集合中即可。
40
41 */
42 public static void method_1()throws IOException
43 {
44 BufferedReader bufr = new BufferedReader(new FileReader("info.txt"));
45
46 String line = null;
47 Properties prop = new Properties();
48
49
50 while((line=bufr.readLine())!=null)
51 {
52 String[] arr = line.split("=");
53 ///System.out.println(arr[0]+"...."+arr[1]);
54 prop.setProperty(arr[0],arr[1]);
55 }
56
57 bufr.close();
58
59 System.out.println(prop);
60 }
61
62
63
64 // 设置和获取元素。
65 public static void setAndGet()
66 {
67 Properties prop = new Properties();
68
69 prop.setProperty("zhangsan","30");
70 prop.setProperty("lisi","39");
71
72 // System.out.println(prop);
73 String value = prop.getProperty("lisi");
74 //System.out.println(value);
75
76 prop.setProperty("lisi",89+"");//修改值
77
78 Set<String> names = prop.stringPropertyNames();
79 for(String s : names)
80 {
81 System.out.println(s+":"+prop.getProperty(s));
82 }
83 }
84
85
86 }
2.1 IO包中的其他类
2.1.1 打印流:
该流提供了打印方法,可以将各种数据类型的数据都原样打印。
字节打印流:
PrintStream
构造函数可以接收的参数类型:
1,file对象。File
2,字符串路径。String
3,字节输出流。OutputStream
字符打印流:
PrintWriter
构造函数可以接收的参数类型:
1,file对象。File
2,字符串路径。String
3,字节输出流。OutputStream
4,字符输出流,Writer。
示例:
1 import java.io.*;
2
3 class PrintStreamDemo
4 {
5 public static void main(String[] args) throws IOException
6 {
7 BufferedReader bufr =
8 new BufferedReader(new InputStreamReader(System.in));//源
9
10 PrintWriter out = new PrintWriter(new FileWriter("a.txt"),true);//目的
11 String line = null;
12
13 while((line=bufr.readLine())!=null)
14 {
15 if("over".equals(line))
16 break;
17 out.println(line.toUpperCase());
18 //out.flush();
19 }
20
21 out.close();
22 bufr.close();
23
24 }
25 }
2.1.2:SequenceInputStream(合并流)
需求:将1.txt、2.txt、3、txt文件中的数据合并到一个文件中
代码:
1 import java.io.*;
2 import java.util.*;
3 class SequenceDemo
4 {
5 public static void main(String[] args) throws IOException
6 {
7
8 Vector<FileInputStream> v = new Vector<FileInputStream>();
9
10
11 v.add(new FileInputStream("c:\\1.txt"));
12 v.add(new FileInputStream("c:\\2.txt"));
13 v.add(new FileInputStream("c:\\3.txt"));
14
15 Enumeration<FileInputStream> en = v.elements();
16
17 SequenceInputStream sis = new SequenceInputStream(en);
18
19 FileOutputStream fos = new FileOutputStream("c:\\4.txt");
20
21 byte[] buf = new byte[1024];
22
23 int len =0;
24 while((len=sis.read(buf))!=-1)
25 {
26 fos.write(buf,0,len);
27 }
28
29 fos.close();
30 sis.close();
2.1.3 切割文件:
需求:文件切割器。
代码:
1 import java.io.*;
2 import java.util.*;
3
4 class SplitFile
5 {
6 public static void main(String[] args) throws IOException
7 {
8 //splitFile();
9 merge();
10 }
11
12
13 public static void merge()throws IOException//合并
14 {
15 ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
16
17 for(int x=1; x<=3; x++)
18 {
19 al.add(new FileInputStream("c:\\splitfiles\\"+x+".part"));
20 }
21
22 final Iterator<FileInputStream> it = al.iterator();//因为这是一个匿名内部类,所以必须要对返回的对象进行final修饰
23
24 Enumeration<FileInputStream> en = new Enumeration<FileInputStream>()
25 {
26 public boolean hasMoreElements()
27 {
28 return it.hasNext();
29 }
30 public FileInputStream nextElement()
31 {
32 return it.next();
33 }
34 };
35
36 SequenceInputStream sis = new SequenceInputStream(en);
37
38
39 FileOutputStream fos = new FileOutputStream("c:\\splitfiles\\0.bmp");
40
41 byte[] buf = new byte[1024];
42
43 int len = 0;
44
45 while((len=sis.read(buf))!=-1)
46 {
47 fos.write(buf,0,len);
48 }
49
50 fos.close();
51 sis.close();
52 }
53
54 public static void splitFile()throws IOException//切割
55 {
56 FileInputStream fis = new FileInputStream("c:\\1.bmp");//关联文件
57
58 FileOutputStream fos = null;
59
60
61 byte[] buf = new byte[1024*1024];
62
63 int len = 0;
64 int count = 1;
65 while((len=fis.read(buf))!=-1)
66 {
67 fos = new FileOutputStream("c:\\splitfiles\\"+(count++)+".part");//碎片文件
68 fos.write(buf,0,len);
69 fos.close();
70 }
71
72 fis.close();
73
74 }
75 }
2.1.4 文件合并器:
需求:文件合并。
1 import java.io.*;
2 import java.util.*;
3
4 public class MergeFile{
5 public static void main(String[] args) throws IOException {
6 File dir = new File("c:\\partFiles" );
7 mergeFile(dir);
8 }
9
10 public static void mergeFile(File dir) throws IOException {
11
12 //获取指定目录下的配置文件对象
13 File[] files = dir.listFiles( new SuffixFilter(".properties" ));
14
15 if(files.length!=1)
16 throw new RuntimeException(dir + ",该目录下没有properties扩展名的文件或者不唯一" );
17
18 //记录配置文件对象
19 File confile = files[0];
20
21 //获取该文件中的信息
22 Properties prop = new Properties();
23 FileInputStream fis = new FileInputStream(confile);
24
25 prop.load(fis);
26
27 String filename = prop.getProperty( "filename");
28
29 int count = Integer.parseInt(prop.getProperty("partcount"));
30
31 //获取该目录下的所有碎片文件
32 File[] partFiles = dir.listFiles( new SuffixFilter(".part" ));
33
34 if(partFiles.length != (count - 1)){
35 throw new RuntimeException("碎片文件不符合要求,个数不对!应该是" + count + "个");
36 }
37
38 //将碎片文件和流对象关联并存储到集合中
39 ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
40
41 for(int x = 1; x <= partFiles.length; x++){
42 al.add( new FileInputStream(partFiles[x-1]));
43 }
44
45 final Iterator<FileInputStream> it = al.iterator();
46
47 //将多个流合并成一个序列流
48 Enumeration<FileInputStream> en = Collections.enumeration(al);
49
50 SequenceInputStream sis = new SequenceInputStream(en);
51
52 FileOutputStream fos = new FileOutputStream(new File(dir,filename));
53
54 byte[] buf = new byte[1024*1024];
55
56 int len = 0;
57
58 while((len = sis.read(buf)) != -1){
59 fos.write(buf,0,len);
60 }
61
62 fos.close();
63 sis.close();
64 }
65 }
66
67 class SuffixFilter implements FilenameFilter{
68 private String suffix;
69
70 public SuffixFilter(String suffix){
71 super();
72 this.suffix = suffix;
73 }
74
75 public boolean accept(File dir,String name){
76 return name.endsWith(suffix);
77 }
78 }