黑马程序员-Java I/O流(二)-File类、Properties类、打印流、序列流(合并流)

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

一、File类

  1. 概述
    是将文件和文件夹封装成的对象,方便对文件或者文件夹的属性信息进行操作。File类的实例是不可变的;一旦创建,File 对象表示的抽象路径名将永不改变,并且可以作为参数传递。
  2. 常用操作方法
File file = new File("a.txt");//将a.txt封装成File对象。可以将已有的和未出现的文件或者文件夹封装成对象。
File file=newFile("c:\\a","b.txt");将文件所在目录路径和文件一起传入,指定文件路径。
file.createNewFile(); // 用于创建一个空文件,成功返回true,若已存在,则不会创建并返回false,
file.mkdir(); // 创建目录,一层(成功返回true,失败返回false)
file.mkdirs(); // 创建多级目录
file.delete(); // 删除成功返回true,否则返回false
file.deleteOnExit(); // 退出时删除,一般用于系统退出时删除临时文件
file.canExecute(); // 是否可被执行
file.exists(); // 是否存在
file.isDirectory(); // 是否为目录文件,不存在或者不是目录返回false
file.isFile(); // 是否为文件,不存在或不是文件返回false
file.isHidden(); // 是否为隐藏文件
file.isAbsolute(); // 是否为据对路径
file.getName(); // 获取文件名
file.getParh(); // 获取文件路径
file.getParent(); // 父目录
file.getAbsolutePath();//获取文件的绝对路径
file.lastModified(); // 最后修改时间
file.length();//返回文件长度
  1. 递归

因为文件目录中会包含子目录,所以想要遍历出所有文件,就需要使用递归。例子如下:

import java.io.File;

 public class Demo {

     public static void main(String[] args) {

         String str = "C:\\";//列出C盘所有文件
         File f = new File(str);
         fun(f);
     }

     //要不断列出,因为给出的File类对象可能是一个目录
    public static void fun(File f){
         //判断给定的路径是否是目录,如果是目录在列出
        if(f.isDirectory()){
             File[] file = f.listFiles();
             //再依次循环进行判断
            try{
                 for(int i = 0;i < file.length;i++){
                     //继续把内容传入到fun方法之中进行验证
                    fun(file[i]);
                 }
             }catch(Exception e){}
         }
         else{
             System.out.println(f);
         }
     }

 }

二、Properties类

  1. 概述
    是Map–Hashtable的子类。一个可以将键值进行持久化存储的对象,键值对都是字符串,无泛型定义。是集合中和IO技术想结合的集合容器。

  2. 常用方法

Properties prop = new Properties();//创建对象  
prop.setProperty(String key,String value);// //设置键和值,调用Hashtable的方法put
prop.getProperty(String key);//指定key搜索value 返回string
prop.load(InputStream ism);//从输入字符流中读取属性列表(键和元素对).
prop.load(Reader reader);   //从输入字符流中读取属性列表(键和元素对)。
prop.list(PrintStream out);//将属性列表输出到指定的输出流
prop.store(OutputStreamout,String comments);//对应load(InputStream )将属性列表(键值对)写入输出流。comments属性列表的描述。
prop.store(Writerwriter, String comments);//对应load(Reader)将属性列表(键值对)写入输出流。comments属性列表的描述。

3示例:

class Demo{
    public static void main()throws IOException
    {
        //使用字符读取缓冲流关联文件
        BufferedReader bufr = new BufferedReader(new FileReader("Test.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();//关流
        System.out.println(prop);
    }
}

三、打印流

  1. 概述
    打印流提供了更多的功能,比如打印方法。可以直接打印任意类型的数据,使用的本机默认的字符编码. 。它有一个自动刷新机制,创建该对象,指定参数,对于指定方法可以自动刷新。

  2. 常用方法

PrintStream(File file)  :创建具有指定文件且不带自动行刷新的新打印流。 
PrintStream(File file, String csn) :创建具有指定文件名称和字符集且不带自动行刷新的新打印流。 
PrintStream(OutputStream out) :创建新的打印流。 
PrintStream(OutputStream out, boolean autoFlush) :创建新的打印流。 
PrintStream(OutputStream out, boolean autoFlush, String encoding) :创建新的打印流。 
PrintStream(String fileName) :创建具有指定文件名称且不带自动行刷新的新打印流。 


 3. 示例:
当目的是一个字节输出流时,如果使用的println方法,可以在printStream对象上加入一个true参数。这样对于println方法可以进行自动的刷新,而不是等待缓冲区满了再刷新。最终print方法都将具体的数据转成字符串,而且都对IO异常进行了内部处理。
因此一般都使用printStream子类PrintWrite,可以直接操作字符数据,同时也可以指定具体的编码。

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("Test.txt"),true);//打印流关联文件,自动刷新

        String line = null;
        while((line=bufr.readLine())!=null)
        {
            out.println(line);
        }

        //关流
        out.close();
        bufr.close();

    }   
}

四、序列流

  1. 概述
    序列流作用就是将多个读取流合并成一个读取流。实现数据合并。

  2. 常用方法
    一般将合并多个流文件步骤:
    1、创建集合,并将流对象添加进集合:ArrayList al = new ArrayList();
    2、创建SequenceInputStream对象,指定集合的枚举对象,合并流:SequenceInputStream sis = new SequenceInputStream(Collections.enumeration(al));
    3、创建写入流对象,FileOutputStream关联写入文件:FileOutputStream fos = new FileOutputStream(file);
    4、利用SequenceInputStream对象和FileOutputStream对象读数据进行反复读写操作:while((len=sis.read(buf))!=-1){
    fos.write(buf,0,len);
    }

具体的合并请看示例:

import java.io.*;
import java.util.*;
class  SplitFileDemo{
    private static final String CFG = ".properties";
    private static final String SP = ".part";
    public static void main(String[] args) throws IOException{
        File file = new File("c:\\0.bmp");
        File dir = new File("c:\\partfiles");
        meger(dir);
    }
    //数据的合并。
    public static void meger(File dir)throws IOException{
        if(!(dir.exists() && dir.isDirectory()))
            throw new RuntimeException("指定的目录不存在,或者不是正确的目录");
        File[] files = dir.listFiles(new SuffixFilter(CFG));
        if(files.length==0)
            throw new RuntimeException("扩展名.proerpties的文件不存在");
        //获取到配置文件
        File config = files[0];
        //获取配置文件的信息。
        Properties prop = new Properties();
        FileInputStream fis = new FileInputStream(config);
        prop.load(fis);
        String fileName = prop.getProperty("filename");//获得文件名
        int partcount = Integer.parseInt(prop.getProperty("partcount"));
        File[] partFiles = dir.listFiles(new SuffixFilter(SP));
        if(partFiles.length!=partcount)
            throw new RuntimeException("缺少碎片文件");

        ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
        for(int x=0; x<partcount; x++){
            al.add(new FileInputStream(new File(dir,x+SP)));
        }
        Enumeration<FileInputStream> en = Collections.enumeration(al);
        SequenceInputStream sis = new SequenceInputStream(en);
        File file = new File(dir,fileName);
        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();
    }

因为上面使用了ArrayList,但是ArrayList没有枚举,所以需要用Enumeration创建。这样会比Vector高效。

五、其他

对象序列化:实现Serializable接口,序列化即使将一个对象整个存储到文件中保存,可以实现数据的保存,下次可以将对象从文件中恢复出,只需要此对象实现了Serializable接口即可,注意的两点是,一是为对象添加static long serialVersionUID = 42L;随便指定一个数值,这是这个对象的唯一标识,即有相同标识才可以从文件中恢复出对象;
二是序列化只会序列化堆中的数据,静态数据不会被序列化,transient关键字的也不会。 如果在不需要序列化的对象,则对象前加上transient关键字。

import java.io.*;
class StreamDemo {
    public static void main(String[] args) throws Exception{
        writeObj();
        readObj();
    }
    public static void readObj()throws Exception{
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt"));
        Object obj = ois.readObject();//读取一个对象。
        System.out.println(obj.toString());
    }
    public static void writeObj()throws IOException{
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.txt"));
        oos.writeObject(new Person("lisi",25)); //写入一个对象。
        oos.close();
    }
}
class Person implements Serializable{
    private static final long serialVersionUID = 42L;
    private transient String name;//用transient修饰后name将不会进行序列化
    public int age;
    Person(String name,int age){
        this.name = name;
        this.age = age;
    }
    public String toString(){
        return name+":"+age;
    }
}

Java序列化就是把对象转换成字节序列,而Java反序列化就是把字节序列还原成Java对象。并且采用Java序列化与反序列化技术,一是可以实现数据的持久化,在MVC模式中很是有用;二是可以对象数据的远程通信。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值