IO流(三)

 Properties类:

 Properties类概述:

  • Properties是hashtable的子类。也就是说它具备map集合的特点。而且它里面存储的键值对都是字符串,不需要泛型定义。
  • Properties是不仅可以操作键值对信息,而且可以操作硬盘上的键值对信息。是集合中和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);  
           
        //setProperty改变的是内存的结果  
        prop.setProperty("wangwu","39");  
  
        FileOutputStream fos = new FileOutputStream("info.txt");  
          
    //haha是注入信息,注释,#代表注释信息,不会被Properties所加载,Properties所加载的信息必须是键值对  
        //那么在加载数据时,需要数据有固定的格式,键=值  
        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)  
        {  
           //split是切割  
            String[] arr = line.split("=");  
            ///System.out.println(arr[0]+"...."+arr[1]);  
            prop.setProperty(arr[0],arr[1]);  
        }  
  
        bufr.close();  
  
        System.out.println(prop);  
    }  
        //设置和获取元素。set和get方法  
    public static void setAndGet()  
    {  
        Properties prop = new Properties();  
          
        //setProperty设置键值对  
        prop.setProperty("zhangsan","30");  
        prop.setProperty("lisi","39");  
   
//      System.out.println(prop);  
        String value = prop.getProperty("lisi");  
        //System.out.println(value);  
          
        //89+""转化成字符型         
        prop.setProperty("lisi",89+"");  
  
        Set<String> names = prop.stringPropertyNames();  
        for(String s : names)  
        {  
            System.out.println(s+":"+prop.getProperty(s));  
        }  
    }  
  
      
}  
配置文件:
用于记录应用程序的运行次数,当运行次数已到,
给出 注册的提示。并不再让该程序执行。

1·很容易想到的是:计数器。
可是该计数器定义在程序中,随着程序的运行而在内存中存在,并进行自增。
可是随着该应用程序的退出,该计数器也在内存中消失了。
2·下一次在启动该程序,又重新开始从0计数。
这样不是我们想要的。
3·程序即使结束,该计数器的值也存在。
下次程序启动在会先加载该计数器的值并加1后在重新存储起来。
4·所以要建立一个配置文件。用于记录该软件的使用次数。
5·该配置文件使用键值对的形式。这样便于阅读数据,并操作数据。
6·键值对数据是map集合。数据是以文件形式存储,使用io技术。那么map+io -->properties.

配置文件可以实现应用程序数据的共享。
现在要用的配置文件有两种:键值对的和xml文件

dom4j: dom for java解析xml文件

import java.io.*;  
import java.util.*;  
class  RunCount  
{  
    public static void main(String[] args) throws IOException  
    {  
        Properties prop = new Properties();  
  
        File file = new File("count.ini");  
        if(!file.exists())  
            file.createNewFile();  
          
        FileInputStream fis = new FileInputStream(file);  
  
        //将流中的数据加载到集合当中  
        prop.load(fis);  
          
  
        int count = 0;  
        String value = prop.getProperty("time");  
          
        if(value!=null)  
        {  
            count = Integer.parseInt(value);  
            if(count>=5)  
            {  
                System.out.println("您好,使用次数已到,拿钱!");  
                return ;  
            }  
  
        }  
  
        count++;  
  
        prop.setProperty("time",count+"");  
  
        FileOutputStream fos = new FileOutputStream(file);  
          
          
        //注入信息没写  
        prop.store(fos,"");  
  
        fos.close();  
        fis.close();  
          
    }  
}  
  
/* 
name=zhangsan 
age=20 
 
 
<persons> 
    <person id="001"> 
        <name>zhagnsan</name> 
        <age>30</age> 
        <address>bj</address> 
    </person> 
    <person> 
        <name>... 
    </person> 
</persons> 
*/  

打印流:

打印流概述:

1、打印流包括:PrintStream和PrintWriter

2、该流提供了打印方法,可以将各种数据类型的数据都原样打印。

字节打印流:PrintStream

构造方法中可接收的参数类型:

1、file对象。File2、字符串路径:String   3、字符输出流:OutputStream

字符串打印流:PrintWriter

构造方法中可接受的参数类型

1、file对象:File2、字符串路径:String3、字节输出流:OutputStream4、字符输出流:Writer

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("a.txt"),true);  
  
        String line = null;  
  
        while((line=bufr.readLine())!=null)  
        {  
            if("over".equals(line))  
                break;  
            out.println(line.toUpperCase());  
            //out.flush();  
        }  
  
        out.close();  
        bufr.close();  
  
    }     
}  

序列流(合并流):

序列流(合并流)概述:

1.序列流SequenceInputStream没有直接对应OutputStream,表示其它输入流的逻辑串联

2·SequenceInputStream可以将多个流连接成一个源

3·构造函数:

    SequenceInputStream(Enumeration<? extends FileInputStream> e)

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是个接口不是类(列举)为了实现遍历枚举也用于将输入流指定到 SequenceInputStream 中。   
                            
     //注:此接口的功能与 Iterator 接口的功能是重复的。此外,Iterator 接口添加了一个可选的移除操作,并使用较短的方法名。  
                         
     //新的实现应该优先考虑使用 Iterator 接口而不是 Enumeration 接口。  
        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();  
    }  
}  

切割流资源:

1、先关联文件FileInputStream

2、定义写入流变量:FileOutputStream

3、创建数组,并定义切割所需的大小|

4、循环读写数据,并每次创建一个新写入流,创建完后并写入文件中

5、关闭流资源

import java.io.*;  
import java.util.*;  
  
class SplitFile   
{  
    public static void main(String[] args) throws IOException  
    {  
        //splitFile();  
        merge();  
    }  
  
  
    public static void merge()throws IOException  
    {  
        ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();  
  
        for(int x=1; x<=3; x++)  
        {  
            al.add(new FileInputStream("c:\\splitfiles\\"+x+".part"));  
        }  
  
        final Iterator<FileInputStream> it = al.iterator();  
  
        Enumeration<FileInputStream> en = new Enumeration<FileInputStream>()  
        {  
            public boolean hasMoreElements()  
            {  
                return it.hasNext();  
            }  
            public FileInputStream nextElement()  
            {  
                return it.next();  
            }  
        };  
  
        SequenceInputStream sis = new SequenceInputStream(en);  
  
  
        FileOutputStream fos = new FileOutputStream("c:\\splitfiles\\0.bmp");  
  
        byte[] buf = new byte[1024];  
  
        int len = 0;  
  
        while((len=sis.read(buf))!=-1)  
        {  
            fos.write(buf,0,len);  
        }  
  
        fos.close();  
        sis.close();  
    }  
  
    public static void splitFile()throws IOException  
    {  
        FileInputStream fis =  new FileInputStream("c:\\1.bmp");  
  
        FileOutputStream fos = null;  
  
  
        byte[] buf = new byte[1024*1024];  
  
        int len = 0;  
        int count = 1;  
        while((len=fis.read(buf))!=-1)  
        {  
            fos = new FileOutputStream("c:\\splitfiles\\"+(count++)+".part");  
            fos.write(buf,0,len);  
            fos.close();  
        }  
          
        fis.close();  
          
    }  
}  

 对象序列化

将堆内存中的对象存入硬盘,保留对象中的数据,称之为对象的持久化(或序列化)

特有方法:

1、write(int val)   --->  写入一个字节(最低八位)

2、writeInt(int vale)  --->   吸入一个32为int值


/* 
对象的序列化 
*/  
  
import java.io.*;  
//对象序列化测试   
class ObjectStreamDemo   
{  
    public static void main(String[] args) throws Exception  
    {      
        //对象写入流  
        writeObj();  
        //对象读取流    
        readObj();  
    }  
    //定义对象读取流   
    public static void readObj()throws Exception  
    {  
        //ObjectInputStream对细节对象进行操作   
        //创建对象读取流    
        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.*;  
//创建Person类,实现序列化  
class Person implements Serializable  
{  
    //定义自身的序列化方式    
    public static final long serialVersionUID = 42L;  
/*serialVersion
给类一个可被编译器识别的的序列号,在编译类时,会分配一个long型UID,通过序列号,
将类存入硬盘中,并序列化,即持久化。序列号根据成员算出的。
静态不能被序列化。如果非静态成员也无需序列化,可以用transien修饰。*/
    //定义私有属性    
    private String name;  
    //age被transient修饰后就不能被序列化了,保证其值只在堆内存中存在,而不再文本文件中存在  
    transient int age;  
    //静态成员变量不能被序列化  
    static String country = "cn";  
    //构造Person类    
    Person(String name,int age,String country)  
    {  
        this.name = name;  
        this.age = age;  
        this.country = country;  
    }  
    //覆写toString方法    
    public String toString()  
    {  
        return name+":"+age+":"+country;  
    }  
}  



管道流:

PipedInputStream和PipedOutputStream是涉及到多线程技术的IO流对象。

步骤:

1、要先创建一个读和写的两个类,实现Runnable接口,因为是两个不同的线程,覆盖run方法,注意,需要在内部抛异常

2、创建两个管道流,并用connect()方法将两个流连接

3、创建读写对象,并传入两个线程内,并start执行

/* 
管道流技术,涉及多线程技术 
*/  
  
import java.io.*;  
//创建Read类,实现run方法    
class Read implements Runnable  
{  
    private PipedInputStream in;  
      
    Read(PipedInputStream in)  
    {  
        this.in = in;  
    }  
    //实现run方法    
    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("管道读取流失败");  
        }  
    }  
}  
//创建Write类    
class Write implements Runnable  
{  
    private PipedOutputStream out;  
    //Write构造函数  
    Write(PipedOutputStream out)  
    {  
        this.out = out;  
    }  
    //实现run方法   
    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 类

RandomAccessFile 类概述:

1、RandomAccessFile称之为随机访问文件的类,自身具备读写方法。

2、该类不算是IO体系中的子类,而是直接继承Object,但是它是IO包成员,因为它具备读写功能,内部封装了一个数组,且通过指针对数组的元素进行操作,同时可通过seek改变指针的位置。

3、可以完成读写的原理:内部封装了字节输入流

4、构造函数:RandomAccessFile(File file,String mode),可已从它的构造函数中看出,该类只能操作文件(也有字符串),而且操作文件还有模式。

模式传入值:”r“:以只读方式打开;”rw“:打开以便读写

如果模式为只读,则不会创建文件,会去读一个已存在的文件,若文件不存在,则会出现异常,如果模式为rw,且该对象的构造函数要操作的文件不存在,会自动创建,如果存在,则不会覆盖,也可通过seek方法修改。

5.RandomAccessFile的最大的作用是实现多线程的下载

特有方法:

1、seek(int n):设置指针,可以将指针设置到前面或后面

2、skipBytes(int n):跳过指定字节数,不可往前跳

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  
    {  
        //"r"代表模式,只读  
        RandomAccessFile raf = new RandomAccessFile("ran.txt","r");  
          
        //seek和skipBytes的区别是:skipBytes不能往回跳,seek可以前后的跳,可以随意改变指针。  
          
        //调整对象中指针。  
        //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();  
    }  
}  

操作基本数据类型的流对象

操作基本数据类型的流对象:DataInputStream和DataOutputStream

这两个读写对象,可用于操作基本数据类型的流对象,包含读写各种基本数据类型的方法

import java.io.*;  
class DataStreamDemo   
{  
    public static void main(String[] args) throws IOException  
    {  
        //writeData();  
        //readData();  
  
        //writeUTFDemo();  
  
//      OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk.txt"),"gbk");  
//  
//      osw.write("你好");  
//      osw.close();  
  
//      readUTFDemo();  
  
    }  
    public static void readUTFDemo()throws IOException  
    {  
        DataInputStream dis = new DataInputStream(new FileInputStream("utf.txt"));  
  
        String s = dis.readUTF();  
  
        System.out.println(s);  
        dis.close();  
    }  
  
  
  
    public static void writeUTFDemo()throws IOException  
    {  
        DataOutputStream dos = new DataOutputStream(new FileOutputStream("utfdate.txt"));  
  
        dos.writeUTF("你好");  
  
        dos.close();  
    }  
  
    public static void readData()throws IOException  
    {  
        DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));  
  
        int num = dis.readInt();  
        boolean b = dis.readBoolean();  
        double d = dis.readDouble();  
  
        System.out.println("num="+num);  
        System.out.println("b="+b);  
        System.out.println("d="+d);  
  
        dis.close();  
    }  
    public static void writeData()throws IOException  
    {  
        DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));  
  
        dos.writeInt(234);  
        dos.writeBoolean(true);  
        dos.writeDouble(9887.543);  
  
        dos.close();  
  
        ObjectOutputStream oos = null;  
        oos.writeObject(new O());  
  
          
    }  
}  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值