黑马程序员-10 IO流2 File,properties,合并流,对象持久化,管道流,RandomAccessFile

File 将文件和文件夹封装成对象

File类常见方法:
1,创建。
boolean createNewFile():在指定位置创建文件,如果该文件已经存在,则不创建,返回false。
和输出流不一样,输出流对象一建立创建文件。而且文件已经存在,会覆盖。

boolean mkdir():创建文件夹。
boolean mkdirs():创建多级文件夹。
2,删除。
boolean delete():删除失败返回false。如果文件正在被使用,则删除不了返回falsel。
void deleteOnExit();在程序退出时删除指定文件。

3,判断。
boolean exists() :文件是否存在.
isFile():
isDirectory();
isHidden();
isAbsolute();

4,获取信息。
getName():
getPath():
getParent():

getAbsolutePath()
long lastModified()
long length()

==============================================================

  
import java.io.File;  
import java.io.IOException;  
import java.text.DateFormat;  
import java.util.Date;  
  
public class FileMethodDemo {  
  
    /** 
     * @param args 
     * @throws IOException 
     */  
    public static void main(String[] args) throws IOException {  
        // getDemo();  
        // createAndDeleteDemo();  
        // isDemo();  
        // renameToDemo();  
        // listRootsDemo();  
    }  
  
    public static void listRootsDemo() {  
        File[] files = File.listRoots();  
        for (File file : files) {  
            System.out.println(file);  
        }  
  
        File file = new File("c:\\");  
        System.out.println(file.getFreeSpace());  
        System.out.println(file.getTotalSpace());  
        System.out.println(file.getUsableSpace());  
    }  
  
    public static void renameToDemo() {  
        File f1 = new File("c:\\0.mp3");  
        File f2 = new File("d:\\9.mp3");  
        f1.renameTo(f2);  
    }  
  
    public static void isDemo() throws IOException {  
        File f = new File("a.txt");  
  
        boolean b = f.exists();  
        System.out.println("exists?:" + b);  
        // 最好先判断是否存在  
        System.out.println("isFile?:" + f.isFile());  
        System.out.println("isDirectory?:" + f.isDirectory());  
    }  
  
    public static void createAndDeleteDemo() throws IOException {  
  
        File dir = new File("abc\\a\\b\\c\\d");  
        // boolean b=dir.mkdir();//创建单级目录  
        // boolean b=dir.mkdirs();//创建多级目录  
  
        // System.out.println("b:"+b);  
        System.out.println("del:" + dir.delete());  
  
        // 文件的创建和删除  
        File file = new File("file.txt");  
        /* 
         * 和输出流不一样,如果文件不存在,则创建;如果文件存在,则不创建。 
         */  
        // boolean b=file.createNewFile();  
        // System.out.println("b:"+b);  
  
        // boolean b=file.delete();  
        // System.out.println("b:"+b);  
    }  
  
    public static void getDemo() {  
        File file = new File("a.txt");  
        String name = file.getName();  
  
        String abspath = file.getAbsolutePath();  
        String path = file.getPath();  
  
        long len = file.length();  
  
        long time = file.lastModified();  
        Date date = new Date(time);  
        DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG,  
                DateFormat.LONG);  
        String str_time = dateFormat.format(date);  
  
        System.out.println("parent:" + file.getParent());// 文件对象中是绝对路径时,获取父目录;相对路径时,null  
  
        System.out.println("name:" + name);  
        System.out.println("path:" + path);  
        System.out.println("abspath:" + abspath);  
        System.out.println("len:" + len);  
        System.out.println("time:" + time);  
        System.out.println("str_time:" + str_time);  
    }  
}  

 


===============================================

Properties是hashtable的子类。
也就是说它具备map集合的特点。而且它里面存储的键值对都是字符串。
是集合中和IO技术相结合的集合容器。
该对象的特点:可以用于键值对形式的配置文件。
那么在加载数据时,需要数据有固定格式:键=值。

import java.io.*;
import java.util.*;

class PropertiesDemo 
{
    public static void main(String[] args) throws IOException
    {
        //method_1();
        loadDemo();
    }

    public static void loadDemo()throws IOException
    {
        Properties prop = new Properties();
        FileInputStream fis = new FileInputStream("info.txt"); //源文件

        //将流中的数据加载进集合。
        prop.load(fis);        //从输入流中读取属性列表(键和元素对)。

        prop.setProperty("wangwu","39");

        FileOutputStream fos = new FileOutputStream("info.txt");

        prop.store(fos,"haha");

    //    System.out.println(prop);
        prop.list(System.out);

        fos.close();
        fis.close();

    }

    //演示,如何将流中的数据存储到集合中。
    //想要将info.txt中键值数据存到集合中进行操作。
    /*
        1,用一个流和info.txt文件关联。
        2,读取一行数据,将该行数据用"="进行切割。
        3,等号左边作为键,右边作为值。存入到Properties集合中即可。

    */
    public static void method_1()throws IOException
    {
        BufferedReader bufr = new BufferedReader(new FileReader("info.txt"));

        String line = null;
        Properties prop = new Properties();


        while((line=bufr.readLine())!=null)
        {
            String[] arr = line.split("=");
            ///System.out.println(arr[0]+"...."+arr[1]);
            prop.setProperty(arr[0],arr[1]);
        }

        bufr.close();

        System.out.println(prop);
    }



//    设置和获取元素。
    public static void setAndGet()
    {
        Properties prop = new Properties();

        prop.setProperty("zhangsan","30");
        prop.setProperty("lisi","39");

//        System.out.println(prop);
        String value = prop.getProperty("lisi");
        //System.out.println(value);
            
        prop.setProperty("lisi",89+"");

        Set<String> names = prop.stringPropertyNames(); 
        for(String s : names)                          
        {
            System.out.println(s+":"+prop.getProperty(s));
        }
    }
}

==========================================================
合并流
SequenceInputStream
表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。

import java.io.*;
import java.util.*;
class SequenceDemo 
{
    public static void main(String[] args) throws IOException
    {

        Vector<FileInputStream> v = new Vector<FileInputStream>();
        
        v.add(new FileInputStream("c:\\1.txt"));
        v.add(new FileInputStream("c:\\2.txt"));
        v.add(new FileInputStream("c:\\3.txt"));

        Enumeration<FileInputStream> en = v.elements();

        SequenceInputStream sis = new SequenceInputStream(en);

        FileOutputStream fos = new FileOutputStream("c:\\4.txt");

        byte[] buf = new byte[1024];

        int len =0;
        while((len=sis.read(buf))!=-1)
        {
            fos.write(buf,0,len);
        }

        fos.close();
        sis.close();
    }
}

===================================================================
对象的持久化(序列化)ObjectOutputStream

import java.io.*;

class ObjectStreamDemo 
{
    public static void main(String[] args) throws Exception
    {
        //writeObj();
        readObj();
    }
    public static void readObj()throws Exception
    {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt"));

        Person p = (Person)ois.readObject();

        System.out.println(p);
        ois.close();
    }

    public static void writeObj()throws IOException
    {
        ObjectOutputStream oos = 
            new ObjectOutputStream(new FileOutputStream("obj.txt"));

        oos.writeObject(new Person("lisi0",399,"kr"));

        oos.close();
    }
}

被传送的类必须是被序列化的,序列号由成员变量生成,类修改之后序列号改变。

import java.io.*;
class Person implements Serializable   //启用Serializable实现其序列化
{
    
    public static final long serialVersionUID = 42L; //自己指定uid,也可以省略有系统生成

    private String name;
    transient int age;    //如果用transient声明一个实例变量,当对象存储时,它的值不需要维持。也就是不能被序列化。
    static String country = "cn";    //    静态变量不能被序列化。(只序列化堆中的变量)
    Person(String name,int age,String country)
    {
        this.name = name;
        this.age = age;
        this.country = country;
    }
    public String toString()
    {
        return name+":"+age+":"+country;
    }
}

 

================================

管道流
PipedInputStream PipedOutputStream
传送输入流应该连接到传送输出流;传送输入流会提供要写入传送输出流的所有数据字节。通常,数据由某个线程从 PipedInputStream 对象读取,并由其他线程将其写入到相应的 PipedOutputStream。不建议对这两个对象尝试使用单个线程,因为这样可能会死锁该线程。传送输入流包含一个缓冲区,可在缓冲区限定的范围内将读操作和写操作分离开。

import java.io.*;

class Read implements Runnable
{
    private PipedInputStream in;
    Read(PipedInputStream in)
    {
        this.in = in;
    }
    public void run()
    {
        try
        {
            byte[] buf = new byte[1024];

            System.out.println("读取前。。没有数据阻塞");
            int len = in.read(buf);    //阻塞式方法
            System.out.println("读到数据。。阻塞结束");

            String s= new String(buf,0,len);

            System.out.println(s);

            in.close();

        }
        catch (IOException e)
        {
            throw new RuntimeException("管道读取流失败");
        }
    }
}

class Write implements Runnable
{
    private PipedOutputStream out;
    Write(PipedOutputStream out)
    {
        this.out = out;
    }
    public void run()
    {
        try
        {
            System.out.println("开始写入数据,等待6秒后。");
            Thread.sleep(6000);
            out.write("piped lai la".getBytes());
            out.close();
        }
        catch (Exception e)
        {
            throw new RuntimeException("管道输出流失败");
        }
    }
}

class  PipedStreamDemo
{
    public static void main(String[] args) throws IOException
    {

        PipedInputStream in = new PipedInputStream();
        PipedOutputStream out = new PipedOutputStream();
        in.connect(out);

        Read r = new Read(in);
        Write w = new Write(out);
        new Thread(r).start();
        new Thread(w).start();
    }
}

 

==================================================================
RandomAccessFile
此类的实例支持对随机存取文件的读取和写入。随机存取文件的行为类似存储在文件系统中的一个大型字节数组。存在指向该隐含数组的光标或索引,称为文件指针;输入操作从文件指针开始读取字节,并随着对字节的读取而前移此文件指针。如果随机存取文件以读取/写入模式创建,则输出操作也可用;输出操作从文件指针开始写入字节,并随着对字节的写入而前移此文件指针。写入隐含数组的当前末尾之后的输出操作导致该数组扩展。该文件指针可以通过 getFilePointer 方法读取,并通过 seek 方法设置。


该类不是算是IO体系中子类。
而是直接继承自Object。

但是它是IO包中成员。因为它具备读和写功能。
内部封装了一个数组,而且通过指针对数组的元素进行操作。
可以通过getFilePointer获取指针位置,
同时可以通过seek改变指针的位置。

其实完成读写的原理就是内部封装了字节输入流和输出流。
通过构造函数可以看出,该类只能操作文件。
而且操作文件还有模式:只读r,,读写rw等。

如果模式为只读 r。不会创建文件。会去读取一个已存在文件,如果该文件不存在,则会出现异常。
如果模式rw。操作的文件不存在,会自动创建。如果存则不会覆盖。

import java.io.*;

class RandomAccessFileDemo 
{
    public static void main(String[] args) throws IOException
    {
        //writeFile_2();
        //readFile();

        //System.out.println(Integer.toBinaryString(258));

    }

    public static void readFile()throws IOException
    {
        RandomAccessFile raf = new RandomAccessFile("ran.txt","r");
        
        //调整对象中指针。
        //raf.seek(8*1);

        //跳过指定的字节数
        raf.skipBytes(8);

        byte[] buf = new byte[4];

        raf.read(buf);

        String name = new String(buf);

        int age = raf.readInt();


        System.out.println("name="+name);
        System.out.println("age="+age);

        raf.close();


    }

    public static void writeFile_2()throws IOException
    {
        RandomAccessFile raf = new RandomAccessFile("ran.txt","rw");
        raf.seek(8*0);
        raf.write("周期".getBytes());
        raf.writeInt(103);

        raf.close();
    }

    public static void writeFile()throws IOException
    {
        RandomAccessFile raf = new RandomAccessFile("ran.txt","rw");

        raf.write("李四".getBytes());
        raf.writeInt(97);
        raf.write("王五".getBytes());
        raf.writeInt(99);

        raf.close();
    }
}

 

======================

 

posted @ 2012-10-26 02:13  EnderViking  阅读(160)  评论(0编辑  收藏  举报