File---------------------------------------------

 

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

方便对文件与文件夹进行操作

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

下面来看一下File类的构造方法:

File file =new File("a.txt");

File file2 =new File("C:\\file\\test\\a.txt");

File d =new File("C:\\file\\test\\");

File file3 =new File(d, "a.txt");

File file4 =new File("C:\\file\\test\\","a.txt");//这和file3是一回事

System.out.println(file +"\r\n" + file2 + "\r\n" + file3 +"\r\n" + file4 + "\r\n");

控制台输出为:

a.txt

C:\file\test\a.txt

C:\file\test\a.txt

C:\file\test\a.txt

但是我们在程序中,文件的路径分隔符只能在windows平台下,在Linux就不能用了,怎么现在跨平台呢?

File file5 = new File("C:"+File.separator+"file"+File.separator+"test"+File.separator+"", "a.txt");

 

接下来就是File类的常用方法了:

创建方法:

 boolean   createNewFile ()在指定位置创建文件,如果文件不存在,则创建成功返回true,如果文件已经存在,则不创建,返回false

这和输出流不同,输出流一旦实例化就会创建文件,文件不存在创建,存在则覆盖.

mkdir ()创建文件夹

mkdirs ()创建文件夹,包括父文件夹

删除方法:

boolean

delete()

void

deleteOnExit()

这两个方法是有区别的:

delete ()根据抽象的路径名称删除文件,如果程序出现异常没有执行到该行代码,那么这个文件就不会被执行,有人会说放在finally执行,但是如果一个程序正在使用该文件,那么这个文件还是不能被删除.

deleteOnExit()这个方法不会发生这种情况,因为该方法在虚拟机停终止,文件就会被删除.

判断方法:

exists ()

canExecute ()应用程序能否执行抽象路径名称所指示的文件 canRead ()应用程序能否读取抽象路径名称所指示的文件

canWrite ()  应用程序能否修改抽象路径名称所指示的文件

isDirectory ()抽象路径名称所指示的是不是文件夹

isFile ()抽象路径名称所指示的是不是文件

isAbsolute ()判断是否是绝对路径

File file =new File("a.txt");

System.out.println("isDirectory:"+file.isDirectory());

System.out.println("isFile:"+file.isFile());

发现控制台输出

isDirectory:falseisFile:false

发现它既不是文件也不是目录,为什么会出现这样的情况呢?

原来用上面的两个方法判断时候,需要先判断该抽象的路径名称所指定的file和directory是否存在.存在才能进行判断.

 

获取信息:

 

File getAbsoluteFile () 返回File对象的绝对路径,但是他把这个字符串封装成了File对象返回 这也是和 getAbsolutePath的主要区别 String getAbsolutePath ()

String getPath () 返回File对象的路径,如果File里的抽象路径名称是绝对路径,如果是相对路径,就返回相对路径 String getName ()如果File对象里的抽象路径名称指定的是目录,那么返回的目录最后的文件夹名称,如果是文件,则返回文件的名称

String getParent () 如果File对象里的抽象路径名称指定的是目录,那么返回的目录最后的文件夹的上一个文件夹的名称,如果是文件,则返回文件所在目录的名称,如果象路径名称指定的是相对路径,有可能返回null,如:File file = new File("a.txt");那么该file的父目录就是null. File getParentFile ()这和 getParent的区别就是 ,这个方法把getParent方法的返回值封装成了File对象 long length ()

renameTo ( File  dest)

例如:

File f =new File("C:\\test\\test.txt");

File f2 =new File("C:\\test\\testDemo.txt");

f.renameTo(f2);

如果盘符或者目录不同这就成了剪切了

 

文件列表:

File [] listRoots () 返回系统盘符的名称 如:C D盘等 String[] list () 返回File目录下的所有文件 如果抽象的路径名称指定的是一个文件将会出现空指针异常;并且该目录一定要存在 例如1:

for(File file: File.listRoots()){

System.out.println(file);

}

输出结果为:

C:\

D:\

E:\

F:\

G:\

例如2:

File file =new File("C:\\");

for

System.out.println(name);

}

输出结果为:C盘目录下的所有文件和目录包含隐藏文件,但是不包含子文件夹里的文件

 

文件过滤:

例如我想输出在某个文件夹下的java文件,那么这时候就要用到过滤文件:

String[] list ( FilenameFilter  filter) 我们查看API不难发现, FilenameFilter  是一个接口里面只有一个方法booleanaccept(File dir,String name)

publicstatic void method_1() {
 
    final File file =new File("D:\\");
 
new
 
    publicboolean
 
        return name.endsWith(".java");
 
        }
 
    });
 
 
    for
 
out.println(name);
 
 
}

下面来看一下:

File[] listFiles () ;这个方法和 list () 方法的区别是 list () 方法是返回一个个字符串的,而 listFiles ()是返回一个个File对象.那么就可以通过File对象获取文件的信息了,所以File[]listFiles()方法更使用一些.例如:

File file =new File("C:\\");
 
for(File file2 : file.listFiles()){
 
System.out.println(file2.getName());
 
}

listFiles ()同样也有自己的过滤功能.通过 listFiles ( FileFilter  filter)

通过递归实现列出目录下的所有文件

publicstatic void main(String[] args) {
 
 
File file =new File("E:\\MyeclipseWorkbenck\\shop");
 
 
method_1(file);
 
 
}
 
  
 
publicstatic void
 
 
System.out.println(file.getAbsolutePath());
 
 
File[] files = file.listFiles();
 
 
for
 
 
if(file2.isDirectory()){
 
 
method_1(file2);
 
 
}else
 
 
System.out.println(file2.getName());
 
 
}
 
 
 
 
}
 
 }

 

删除带目录的文件,如果直接使用delete方法,则不能删除成功,因为java删除文件的原理是这样的,把最里面的文件删除,然后删除文件夹

publicstatic void main(String[] args) {
 
 
new File("D:\\java");
 
 
    deleteDir(file);
 
 
}
 
 
publicstatic void
 
 
    File[] files = file.listFiles();
 
 
    for(File file2 : files){
 
 
    //如果是目录
 
 
        if(file2.isDirectory()){
 
 
    //则使用递归 调用本身
 
 
        deleteDir(file2);
 
 
else
 
 
    //不是目录就直接删除
 
 
        file2.delete();
 
 
    }
 
 
    }
 
 
    //然后删除空文件夹
 
 
    file.delete();
 
 }

 

怎么把java文件的路径存在一个文件里面,方便以后查找.

publicclass JavaFileItem {
 
 
publicstatic void
 
 
new
 
 
    saveJavaFilePath(new File("E:\\MyeclipseWorkbenck\\HeimaTest"), list);
 
 
    writeFilePath(list,"javaItem.txt");
 
 
}
 
 
//则把java文件放在集合中
 
 
publicstatic void
 
 
    File[] files = dir.listFiles();
 
 
    for
 
 
        if
 
 
            saveJavaFilePath(file, list);
 
 
else
 
 
    //如果是java文件,则把该文件放在集合中
 
 
        if (file.getAbsolutePath().endsWith(".java"))
 
 
            list.add(file);
 
 
        }
 
 
    }
 
 
    }
 
 
//把java的路径信息写入文件中
 
 
publicstatic void
 
 
BufferedWriter buffw =null;
 
 
try
 
 
new
 
 
new
 
 
        for
 
 
            //把java文件的绝对路径写入文件
 
 
            buffw.write(file.getAbsolutePath());
 
 
            //换行
 
 
            buffw.newLine();
 
 
            //使用字符流注意刷新
 
 
            buffw.flush();
 
 
        }
 
 
catch
 
 
        e.printStackTrace();
 
 
finally
 
 
        try
 
 
            if (buffw !=null)
 
 
                buffw.close();
 
 
catch
 
 
                e.printStackTrace();
 
 
            }
 
 
        }
 
 
    }
 
 }

这里就是使用递归和IO操作的结合了.

关于Properties类:--------------------------------------------

 

关于Properties类:

Properties是Hashtable的子类,也就是说它具备map结婚的特点,而且它里面存储的键值对都是字符串

他是集合和IO相结合的集合容器

该对象的特点是可以用于键值对形式的配置文件

getProperty ( String  key) 根据key从Properties对象中获取值 setProperty ( String  key, String  value) 为Properties对象设置key和value store ( OutputStream  out, String  comments) 把Properties对象储存到一个文件里面去,底层通过字节输出流处理 store ( Writer  writer, String  comments) 这是JDK1.6后才有的,直接使用字符输出流就可以把Properties对象储存到文件中 load ( InputStream  inStream) 读取属性列表从字节输入流中,加载某个键值对文件,使得Properties与该文件相关联 load ( Reader  reader) 这是JDK1.6后才出现的,读取属性列表从字符输入流中,

模拟限制软件使用次数:

publicstatic void count()throws IOException{
 
 
new
 
 
new File("count.ini");
 
 
    if(!file.exists()){
 
 
        file.createNewFile();
 
 
    }
 
 
new
 
 
    properties.load(is);
 
 
"times");
 
 
    int
 
 
    if(times!=null){
 
 
        count = Integer.parseInt(times);
 
 
        if(count>=5)
 
 
"你使用的次数已到,请续费!");
 
 
    }
 
 
    count++;
 
 
new
 
 
"times", count+"");
 
 
"count times");
 
 
    os.close();
 
 
    is.close();
 
 }

 

打印流---------------------------------------------------------------------------

下面学习打印流对象PrintStream  PrintWriter

PrintStream

也就是说一个字节数组被写入或者调用println方法或者写入了换行字符或者字节\n 后这个flush方法会被自动调用

PrintStream的常用的构造方法:

PrintStream ( File  file) PrintStream ( OutputStream  out) PrintStream ( OutputStream  out, boolean autoFlush) PrintStream ( String  fileName) PrintStream ( OutputStream  out, boolean autoFlush, String  encoding)

PrintWriter的API

大概的意思是说,PrintWriter类不像PrintStream类,如果设置了自动刷新(PrintWriter(Writer out, boolean autoFlush) 或者通过PrintWriter(OutputStream out, boolean autoFlush)),只有当调用println()printf() format()方法才会被刷新,而不是无论什么时候只要出现换行字符就会输出,这些方法使用的是平台自己的行分隔符标准,而不是使用换行字符.

接着看一下他的主要构造方法:

PrintWriter ( File  file)

PrintWriter ( String  fileName) PrintWriter ( OutputStream  out) PrintWriter ( OutputStream  out, boolean autoFlush) PrintWriter ( Writer  out) PrintWriter ( Writer  out, boolean autoFlush)

比较PrintStream和PrintWriter的构造方法的最大区别PrintWriter可以接受字符输出流Writer而PrintStream不能,所以PrintWriter更常用.

下面通过一个实例来运用它:

publicstatic void print()throws IOException{
 
 
    //获取键盘输入
 
 
new BufferedReader(new InputStreamReader(System.in));
 
 
    //目的是控制台
 
 
new PrintWriter(System.out);
 
 
null;
 
 
    while((value=buffr.readLine())!=null){
 
 
        pw.write(value);
 
 
        //注意刷新
 
 
        pw.flush();
 
 
    }
 
 
    pw.close();
 
 
    buffr.close();
 
 
 
 }

控制太输出如下:

发现他没有换行,看上去不美观:怎么实现换行呢?我们来看一下这两个个方法

println ( String  x)

println()

API是这样解释 println ( String  x)方法的Prints a String and then terminates the line. This method behaves as though it invokes print(String) and then println().

先打印字符串然后终止这行,也就是先调用print(String str)方法然后在调用println()方法.

 

println() 方法 的

Terminates the current line by writing the line separator string. The line separator string is defined by the system property line.separator, and is not necessarily a single newline character ( '\n'). 也就是通过行分隔符终止当前行,行分隔符通过系统属性 line.separator设置的而不需要简单的换行符'\n'

是不是我们通过println();方法就可以解决上面的问题呢?

while((value=buffr.readLine())!=null){
 
 
     pw.write(value);
 
    pw.println();//终止一行
 
    //手动刷新
 
    pw.flush();
 
}

 pw.flush();注释掉如:

PrintWriter pw =new PrintWriter(System.out,true);//设置自动刷新
 
String value =null;
 
while((value=buffr.readLine())!=null){
 
    pw.write(value);
 
();//因为println()printf()format()都会触发刷新
 
pw.flush();
 
}

 

我们还可以不使用write(),使用println(String)就会更加简单

PrintWriter pw =new PrintWriter(System.out,true););//设置自动刷新
 
String value =null;
 
 
while((value=buffr.readLine())!=null){
 
 
();//因为println()printf()format()都会触发刷新
 
 }

 

我们还可以猜想:

PrintWriter pw =new PrintWriter(System.out,true););//设置自动刷新
 
 
String value =null;
 
 
while((value=buffr.readLine())!=null){
 
 
pw.write(value+"\r\n");//末尾加上换行符是否会触发自动刷新呢?
 
 }

在PrintWriter的API有这样一句话These methods use the platform's own notion of line separator rather than the newline character. 也就是说

是否会触发自动刷新,java内部不是使用换行符("\r\n")而是使用平台内部的行分隔符(当然在windows他们是一样的).

"line.separator"

我们来测试一下

PrintWriter pw =new PrintWriter(System.out,true););//设置自动刷新

while((value=buffr.readLine())!=null){

pw.write(value+System.getProperty("line.separator"));//我们使用writer方法,里面的字符串参数加上行分隔符,因为java api里面说println()因为内部加上了行分隔符才会触发刷新的,那么现在我们手工加上行分隔符会触发刷新吗?

}

测试的结果还是不行!

那么为什么?java不是要系统的行分隔符吗?我现在已经加上了行分隔符还不行呢?

我们来看一下PrintWriter的源代码是怎么定义println(String)方法的

println(String)的定义:

    publicvoid

        synchronized

先打印数据

/再打印行分隔符,我们在进入println()是怎么定义的,

        }

    }

 

println()的定义:

    publicvoid

();//打开是怎么样定义的

    }

newLine()方法的定义:

privatevoid newLine() {
 
 
    try
 
 
        synchronized
 
 
        ensureOpen();
 
 
        out.write(lineSeparator);//写入行分隔符
 
 
        if
 
 
            out.flush();//如果设置为true,那么调用flush()方法
 
 
        }
 
 
    } 
  catch
 
 
        Thread.currentThread().interrupt();
 
 
    } 
  catch
 
 
true;
 
 
    }
 
 }

经过我查看writer()方法的源代码,没有发现他去判断是否刷新,

结论:尽管我们在使用writer(String)方法的String参数后面加上了行分隔符,但是在writer方法里面根本不去判断是否设置了autoFlush=true

所以我们在writer(String)方法的String参数后面加上了行分隔符也不能达到预期的效果!

如果我们想更加了解PrintStream和PrintWriter的区别,查看源代码是最好的帮手.PrintStream是字节输出流的子类,PrintWriter是字符输出流的子类.

 

 

序列流-合并流---------------------------------------------------------------------

简单的说就是把多个字节输入流合并成一个字节输入流,

SequenceInputStream ( Enumeration <? extends InputStream > e) 里面传一个 Enumeration里面的元素使用了泛型限定. SequenceInputStream ( InputStream  s1, InputStream  s2) 里面传入两个字节输入流对象 实例:怎么把3个文件的内容输入到一个文件中:

//通过Vector可以获取Enumeration
 
 
Vector<InputStream> vector =new
 
 
vector.add(new FileInputStream("C:\\1.txt"));
 
 
vector.add(new FileInputStream("C:\\2.txt"));
 
 
vector.add(new FileInputStream("C:\\3.txt"));
 
 
//实例化合并流
 
 
SequenceInputStream sequence =new
 
 
InputStreamReader isr =new
 
 
BufferedReader fr=new
 
 
BufferedWriter bw =new BufferedWriter(new FileWriter("C:\\123.txt"));
 
 
String value =null;
 
 
while((value=fr.readLine())!=null){
 
 
bw.write(value);
 
 
bw.newLine();
 
 
}
 
 
bw.close();
 
 sequence.close();

 

切割流----------------------------------------------------------------------

需求  :一个MP3文件切割成几个文件:

 

publicstatic void cut()throws Exception {

new FileInputStream("C:\\mp3\\卓依婷- 好人好梦.mp3");

null;

    byte[] buffer =new byte[1024*1024];

    int

    int

    while

        //每一次循环都会生成一个文件,这样就实现了切割

new FileOutputStream("C:\\mp3\\part\\"+(name++)+".part");

        //每个文件写1M,最后一个文件可能没有1M

        os.write(buffer,0,len);

        os.close();

    }

    is.close();

}

发现part目录多了4个文件,并且大小和以前的文件一样:

从而也验证了前面4个文件都是1M最后一个没有1M的结论

现在怎么把上面的4个文件重新合并成一个文件

publicstatic void merger()throws Exception {
 
 
new
 
 
    for (int
 
 
new FileInputStream("C:\\mp3\\part\\" + (i) +".part"));
 
 
    }
 
 
    final
 
 
new
 
 
    publicboolean
 
 
    return
 
 
    }
 
 
    public
 
 
    return
 
 
}
 
 
};
 
 
new
 
 
new FileOutputStream("C:\\mp3\\part\\卓依婷- 好人好梦.mp3");
 
 
    byte[] buffer =new byte[1024];
 
 
    int
 
 
    while((len=sequence.read(buffer))!=-1){
 
 
        os.write(buffer,0,len);
 
 
    }
 
 
    os.close();
 
 
    sequence.close();
 
 }