Java中的IO框架流三

1      IO(三)No20

1.1    Properties 属性集

Properties 属性集,主要用于操作配置属性,

是以键值对的方式来保存属性,并且都是String类型

继承自Hashtable类,所以是一个Map集合,具有Map接口中的所有方法,但是在保存和读取数据的时候不建议使用put和get方法,因为有可能会出现异常,建议使用Properties中特有的方法进行数据的存储

常用方法:

1、添加、获取

   setProperty(String key,String value):添加键值对

   getProperty(String key):通过键获取值《getProperty(String key)

getProperty(String key, String defaultValue)》如果键不存在返回默认值

2、保存、加载(配合IO流使用)

   store():将数据通过输出流写到指定文件中

store(OutputStream out, String comments)

store(Writer writer, String comments)  参数二:代表注释

   load():通过输入流读取指定文件中的数据

load(InputStream inStream)    load(Reader reader)

3、遍历数据

   list():将集合中的所有数据输出到指定的流中(一般用于调试)

list(PrintStream out)      list(PrintWriter out)

   stringPropertyNames():获取集合中键的集合(键的类型是String类型)

1.1.1  示例程序

publicclass Demo {

 

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

                  

                   Properties prop = newProperties();

                  

                   /*

                    * Properties类继承于Hashtable类,所以可以使用put方法添加键值对,

                    * 但是Properties类中的数据要求应该都是String类型,使用put方法返回可能会出问题

                    * 官方建议使用setProperty()方法添加键值对

                    */

        

//               prop.put("textsize",18);

//               prop.get("textsize");

                  

                   //保存值

                   prop.setProperty("textsize","18");

                   prop.setProperty("textcolor","red");

                   //获取值

                   String size =prop.getProperty("textsize");

                   String color=prop.getProperty("textcolor");

                   System.out.println(size);

                   System.out.println(color);

                  

                  

                   //将属性保存到磁盘上

                   //Properties的作用是将数据持久化保存,实际上就是将数据保存在磁盘上

//               prop.save(out, comments);

                   FileOutputStream fos = new FileOutputStream("prop.properties");

                   prop.store(fos, "注释");

                  

                   //从磁盘上读取属性数据

                   Properties prop2 = newProperties();

                   FileInputStream fis = newFileInputStream("prop.properties");

                   prop2.load(fis);

                   System.out.println(prop2);

                  

                   //遍历Properties集合(是Map集合)

                   //list方法一般是用于调试用的

                   prop2.list(System.out);

                   //传统的遍历Map集合的方式,通过keyset方法获取键的集合,但是元素都是Object类型

//               prop2.keySet();

                  

         Set<String>     keyset = prop2.stringPropertyNames();

                   for (String key : keyset) {

                            String value =prop2.getProperty(key);

                            System.out.println(key+"..........."+value);

                   }

                  

         }

 

}

实例:写一个程序,要求用户只能打开5次,在第6次打开的时候就抛出异常提示“打开失败”

publicclass Ex {

 

         public static void main(String[] args){

                   System.out.println("程序开启.......");

                   //检测使用的次数

                   check();

                   System.out.println("程序正常运行.......");

                   System.out.println("程序结束.......");

         }

 

        

         private static void check() {

                   /*

                    * 思路:记录用户打开程序的次数,每次打开的时候都记一次,将次数保存在配置文件中,

                    * 每次打开的时候读取上一次记录的次数,如果超出上限,就提示用户

                    */

                   //

                   FileInputStream fis =null;

                   FileOutputStream fos = null;

                   try {

                            Properties prop =new Properties();

                            File file = newFile("prop_ex.properties");

                            //要保证文件存在

                            if(!file.exists()){

                                     file.createNewFile();

                            }

                             fis = new FileInputStream(file);

                            //从文件中加载数据到Properties集合中

                            prop.load(fis);

                            //通过键获取值,如果键值对不存在,就返回指定的默认值

                            int count=Integer.parseInt(prop.getProperty("count","0"));

                            count ++;

                            //判断打开的次数是否已经超过了上限

                            if(count>5){

                                     throw newRuntimeException("适用用次数已经超过5次上限,请续费!.......");

                            }else{

                                     //如果没有超过

                                     fos = newFileOutputStream(file);

                                     prop.setProperty("count",String.valueOf(count));

                                     prop.store(fos,"open count");

                            }

                   } catch (IOException e) {

                            // TODO: handleexception

                   }finally{

                            if(fos != null){

                                     try {

                                               fos.close();

                                               fos= null;

                                     } catch(IOException e) {

                                               //TODO Auto-generated catch block

                                               e.printStackTrace();

                                     }

                            }

                            if(fis != null){

                                     try {

                                               fis.close();

                                               fis= null;

                                     } catch(IOException e) {

                                               //TODO Auto-generated catch block

                                               e.printStackTrace();

                                     }

                            }

                   }

                  

         }

 

}

 

1.2    内存流

数组流

                   byte[] bytes ={97,98,99,100,101};//源字节数组

                   ByteArrayInputStream bais =//在源数组上创建一个内存输入流

                                     newByteArrayInputStream(bytes);

                   int n=0;

                   byte[] buf = new byte[4];

                   //4个字节放到缓冲buf中,返回有效读取数

                   while((n=bais.read(buf))!=-1){

                            for(int i=0;i<n;i++){//从缓存0开始遍历,遍历到-1

                                     System.out.println(buf[i]);  //打印

                            }

                   }

         }

         //不需要关闭

                   //创建一个内存输出流,可以通过它向内置的字节数组中写字节

                   ByteArrayOutputStream baos=new ByteArrayOutputStream();

                   baos.write(65);//往内置字节数组中写一个字节

                   baos.write(66);

                   baos.write(67);

                   //从中拿出之前写的字节生成的数组

                   byte[] array =baos.toByteArray();

                   for(byte b : array){//遍历打印,用于验证

                            System.out.println(b);

                   }

         //源文件流

                   FileInputStream fis = newFileInputStream("g:/output.txt");

                   //目标内存输出流

                   ByteArrayOutputStream baos=new  ByteArrayOutputStream();

                   int n=0;

                   byte[] buf = new byte[4];//缓冲数组创建

                   //每次从文件读4个字节方法缓冲中,有效字节数赋给n,-1比较判断是否读完

                   while((n=fis.read(buf))!=-1){

                            baos.write(buf,0,n);   //没有读完就将有效字节写到内存输出流

                   }

                   fis.close();//需要关闭

//               baos.close();//不需要关闭

                   byte[]array=baos.toByteArray();   //获取字节数组

                   for (byte b : array) {//遍历,验证

                            System.out.println((char)b);

                   }

FileInputStream fis =new FileInputStream(

                                     "g:/mysql-connector-java-5.1.7-bin.jar");

                   ByteArrayOutputStream baos =new ByteArrayOutputStream();

                   int n = 0;

                   byte[] buf = newbyte[1024];// 缓冲

                   while ((n = fis.read(buf)) !=-1) {// 从文件读1024字节,有效字节数赋值给n,-1比较判断是否结束

                            baos.write(buf, 0,n);// 把有效字节写到内存输出流

                   }

                   fis.close();

                   byte[] array =baos.toByteArray(); // 用写进的字节生成数组

                   // 准备从这个字节数组中读字节

                   ByteArrayInputStream bais =new ByteArrayInputStream(array);

                   FileOutputStream fos = newFileOutputStream("g:/copy.jar");

                   while ((n = bais.read(buf))!= -1) {// 从数组读1024字节,有效字节数赋给n,-1比较

                            fos.write(buf, 0,n); // 把有效字节写到copy.jar

                   }

                   fos.close();

                   FileInputStream fis = newFileInputStream("g:/mysql-connector-java-5.1.7-bin.jar");

                   ByteArrayOutputStream baos=new ByteArrayOutputStream();

                   int n= 0;

                   byte[] buf = new byte[1024];

                   while((n=fis.read(buf))!=-1){//读源文件只进行一次

                            baos.write(buf,0,n);

                   }

                   fis.close();

                   byte[] array =baos.toByteArray();

                   //把文件放到内存中,这些动作不重复进行,这些动作包含了对磁盘的操作

                   //把内存中的内容拷贝到文件,重复进行

                   for(int i=1;i<=100;i++){

                            ByteArrayInputStreambais = new ByteArrayInputStream(array);

                            FileOutputStream fos= new FileOutputStream("g:/100/"+i+".jar");

                            //这里也要读100次,但是每次都是读内存数组,所以效率大大提高

                            while((n=bais.read(buf))!=-1){

                                     fos.write(buf,0,n);

                            }

                            fos.close();

                   }

内存流(字节数组)节点流、字节流

ByteArrayInputStream

ByteArrayOutputStream

构造方法:

ByteArrayInputStream(byte[]bytes)创建一个内存流,可以从参数字节数组中读取字节

常用方法:

int read()

int read(byte[] buf)

不需要调用close()方法

 

构造方法:

ByteArrayOutputStream()创建一个内存输出流,无参数,可以往内置的字节数组中写字节

常用方法:

write(int b)

write(byte[] buf,intoff,int len)

不需要调用close()方法

toByteArray() 获得字节数组(之前写到其中的字节组成的字节数组)

 

在文件小且不经常变更的情况下,可以用内存流先进行缓存,避免反复磁盘操作

 

实例:

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

                   //字节数组输出流

                   //是以数组作为数据源,将数据写到数组中

                   //当数组输出流被创建的时候内部会自动创建一个数组

                   ByteArrayOutputStream baso =new ByteArrayOutputStream();

                   //将数据写出到数组流内部的数组(内存)中

                   baso.write("强风125".getBytes());

                   //取出流中的字节数组

                  byte[]buf  =baso.toByteArray();

                   System.out.println(newString(buf));

                   //在这里因为操作的是内存,所以不需要释放存放

//               baso.close();

                  

                   //使用场景:从网上下载图片并显示在界面上

                  

                  

                   //从内存数组中去数据

                   ByteArrayInputStream bais =new ByteArrayInputStream(buf);

                   byte[] cubf  = new byte[1024];

                   bais.read(cubf);

                   System.out.println(newString(cubf));

                   //如果一个数组中的数据比较多,需要分批读取,那么使用数组流能简化我们的代码

                   //比如:现在有一个字节数组大小为1000,每次读取300个字节,自到将数据读完       

         }

1.3    对象流

对象流是一种处理流、字节流

对象流

   ObjectInputStream

                   readObject()

         ObjectOutputStream

                   writeObject()

注意事项:

1、 被对象流操作的对象必须先进行序列化(实现Serializable接口)

1)       需要在类中定义一个静态常量(序列值,static final longserialVersionUID)

2)       在数据序列化的时候不会对静态字段(static )和瞬态字段(transient)进行序列化

2、一个文件只能存储一个对象

 

实例:

publicclass Demo {

 

         public static void main(String[] args)throws IOException, ClassNotFoundException {

//               test1();

//               writeObj();

                   readObj();

                  

         }

 

         private static void readObj() throwsIOException, ClassNotFoundException {

                   FileInputStream fis = newFileInputStream("objdemo.object");

                   ObjectInputStream ois = new ObjectInputStream(fis);

                   //内部自动进行了反序列化

                   Student stu =(Student)ois.readObject();

                   System.out.println(stu);

         }

 

         private static void writeObj() throwsIOException {

                    Student stu = new Student("小强", "男", 18);

                    //对象流,用于直接操作对象

                    FileOutputStream fos = newFileOutputStream("objdemo.object");

                    ObjectOutputStream oos = newObjectOutputStream(fos);

                    

                    //将对象写出到指定设备

                    //注意:对象流操作的对象必须进行序列化

                    //序列化:只需要实现Serializable

                    oos.writeObject(stu);

                    oos.close();

         }

 

         private static void test1() throwsIOException, FileNotFoundException {

                   Student stu = newStudent("小强","男", 18);

                    FileWriter fw =  newFileWriter("object.txt");

                    fw.write(stu.name+"|");

                    fw.write(stu.gender+"|");

                    fw.write(stu.age +"");

                    fw.close();

                    

                    //从磁盘上读取对象的数据并生成对象

                    BufferedReader br = new BufferedReader(newFileReader("object.txt"));

                    String line = br.readLine();

                    String[] strs = line.split("\\|");

                    String name = strs[0];

                    String gender = strs[1];

                    int age = Integer.parseInt(strs[2]);

                    Student stu2 = new Student(name, gender, age);

                    System.out.println(stu2);

         }

 

}

 

classStudent implements Serializable/*标记接口*/{

         /**

          * 序列值,用于标记类的唯一性

          * 如果没有指定序列值,那么编译器会自动根据类中的成员来自动生成一个序列值

          * 建议:在序列化的时候最好要写上序列值

          */

         private static final long serialVersionUID= 10000L;

         /**

          * static 修饰的类成员不会被序列化

          */

         String name;

         String gender;

         transient int age;     //瞬态的(不会进行序列化)

         public Student(String name, Stringgender, int age) {

                   this.name = name;

                   this.gender = gender;

                   this.age = age;

         }

         @Override

         public String toString() {

                   return "Student[name=" + name + ", gender=" + gender + ", age=" + age

                                     +"]";

         }

        

}

1.3.1  ObjectOutputStream

//文件的文件输出流

                   FileOutputStream fos = newFileOutputStream("g:/obj");

                   //用对象输出流去处理、装饰fos文件输出流

                   ObjectOutputStream oos = newObjectOutputStream(fos);

                   oos.writeObject("1000phone");//写一个字符串对象到流中

                   oos.close();

//对象流装饰文件流

                   ObjectOutputStream oos = newObjectOutputStream(

                                     newFileOutputStream("g:/elephant"));

                   //初始化对象

                   Elephant mike = newElephant("Mike", 1000);

                   oos.writeObject(mike);    //把大象塞进去

                   oos.close();

 

构造方法:ObjectOutputStream(OutputStream os)参数是它要处理、装饰的流,增加了写对象的功能

writeObject(Objectobj)

 

 

1.3.2  ObjectInputStream

ObjectInputStream ois= //用对象流装饰文件流

                                     newObjectInputStream(new FileInputStream("g:/obj"));

                   String str =(String)ois.readObject();   //读一个对象

                   System.out.println("obj文件中拿出来了:"+str);

                   ois.close();

ObjectInputStream ois= new ObjectInputStream(

                                     newFileInputStream("g:/elephant"));

                   //把大象从流中拖出来,拿到的是Object类型,强转为大象类型

                   Elephant e =(Elephant)ois.readObject();

                   System.out.println(e.getName()+"   "+e.getWeight());

                   ois.close();

 

构造方法:ObjectInputStream(InputStream is)参数是它要处理、装饰的流,增加了读对象的功能

Object readObject()

 

对象流读写,写的和读的类型一定要一致。

对象流读写的对象必须要可序列化,必须实现Serializable接口,这个接口无抽象方法。

用途:信息的存储、信息在网络上的传递、信息在组件间传递

 

1.4    输出流(打印流)

PrintWriterpw = new PrintWriter(

                                     newFileOutputStream("g:/answer.txt",true));

                   //由于构造方法第二个参数为true ,println会自动刷缓存

                   pw.println("1000phone");//打印1000phone到文件中并换行

                   pw.println("android");//打印android到文件中并换行

                   pw.println("java");//打印java到文件中并换行

                   pw.close();

PrintWriter  输出流、字符流、处理流

构造方法:

PrintWriter(OutputStreamos,boolean autoFlush)第一个参数是所要装饰的字节输出流,第二个参数是表示是否自动刷缓存

PrintWriter(Writerwriter,boolean autoFlush)装饰字符流

PrintWriter(StringpathString csn) 在以第一个参数为路径的文件上建立打印流,字符集由第二个参数指定

println() 打印并且换行,在autoFlush为true时,会自动刷缓存

 

PrintStream 用法和PrintWriter差不多,构造方法少一点

 

实例

publicstatic void main(String[] args) throws IOException {

                   // 打印流(只有输出流)PrintStream(字节打印流)  PrintWriter (字符打印流)

//               PrintStream ps = new PrintStream(newFileOutputStream("print.txt"));

                  

                   PrintStream ps = newPrintStream("print.txt");

                   /*ps.print(true);

                   ps.print("中");

                   ps.print("f");*/

                   ps.print(18);    //编码

                   ps.write(97);    //字面值

                   ps.close();

         }

 

1.5    数据流

DataOutputStream dos= //用数据流装饰文件流

                                     newDataOutputStream(new FileOutputStream("g:/answer.txt"));

                   dos.writeInt(101);//向数据流中写100

                   dos.writeInt(100);

                   dos.writeInt(70);

                   dos.writeInt(66);

                   dos.close();//关闭处理会自动关闭所装饰的流

DataInputStream dis =new DataInputStream(

                                     new FileInputStream("g:/answer.txt"));

                   int a=dis.readInt();//用数据流装饰文件流

                   System.out.println(a);

                   System.out.println(dis.readInt());//打印读出的int数据

                   System.out.println(dis.readInt());

                   System.out.println(dis.readInt());

                   dis.close();

DataOutputStream 数据输出流,字节流、处理流

DataOutputStream(OutputStreamos)构造方法参数为它所装饰的字节输出流,添加了写基本类型数据的功能

writeInt(int i)

writeXXX(xxx i)

 

DataInputStream 数据输入流

DataInputStream(InputStreamis)构造方法参数为它所装饰的字节输入流,添加了读基本数据类型的功能

int readInt()

xxx readXXX()

 

实例:

publicstatic void main(String[] args) throws IOException {

                  

                   //数据流(过滤流)

                   FileOutputStream fos = newFileOutputStream("data.txt");

                   DataOutputStream oos = newDataOutputStream(fos);

                   oos.writeByte(100);

                   oos.writeChar('中');

                   oos.writeShort(1000);

                   oos.writeInt(1022);

                   oos.writeLong(12025);

                   oos.writeFloat(12.2f);

                   oos.writeDouble(15.4524);

                   oos.writeBoolean(true);

                   oos.close();

                  

                   //读取数据

            FileInputStream fis = new FileInputStream("data.txt");

            DataInputStream dis = new DataInputStream(fis);

            System.out.println(dis.readByte());

            System.out.println(dis.readChar());

            System.out.println(dis.readShort());

            System.out.println(dis.readInt());

            System.out.println(dis.readLong());

            System.out.println(dis.readFloat());

            System.out.println(dis.readDouble());

            dis.close();

         }

 

1.6    装饰模式

装饰模式:

1、把被装饰者通过构造方法传入装饰者

2、被装饰者和装饰者具有相同的方法(方法名、返回、参数)、具有相同的接口或父类

3、被装饰者以属性的形式存在于装饰者中

1.7    随机访问文件

RandomAccessFile raf= new RandomAccessFile("g:/answer.txt", "rw");

                   raf.write(65);//A|

                   raf.write(66);//AB|

                   raf.seek(0);//将游标一下子跳到第一个位置|AB

                   raf.write(67);

                   raf.write(68);

                   raf.close();

RandomAccessFile raf=new RandomAccessFile("g:/answer.txt", "r");

                   System.out.println(raf.read());

                   System.out.println(raf.read());

                   raf.seek(0);  //游标放到最前

                   System.out.println(raf.read());

                   System.out.println(raf.read());

                   raf.close();

RandomAccessFile  随机访问文件,不是InputStream、OutputStream、Reader、Writer中的任一个子类

RandomAcceessFile(Stringpath,String mode)

构造方法第一个参数表示文件路径,第二个参数打开模式,如果是"rw"表示可读可写,如果是"r"表示只读

seek(int pos) 定位,游标可以随便向前向后跳,只要不超出范围(Stream、Reader、Writer只能往后不能往前)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值