4、特殊操作流

System类中有两个静态的成员变量

public static final InputStream in 标准输入流

public static final PrintStream out 标准输出流

4.1、标准输入流

package itheima01;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Scanner;

//public static final InputStream in 标准输入流,通常该流对应键盘输入或由主机环境或用户指定的另一个输入源
public class SystemInDemo {
    public static void main(String[] args) throws IOException {
//        public static final InputStream in 标准输入流
//        InputStream被final修饰说明他是个常量
//        InputStream被static修饰说明他可以通过类名直接访问in
        InputStream is = System.in;
//        一次读一个字节
        /*int by;
        while((by=is.read())!=-1){
            System.out.println((char) by);
        }*/
//        如何把字节流转换为字符流?使用转换流
//        InputStreamReader isr=new InputStreamReader(is);
//        使用字符流能不能够实现一次读取一行数据呢   可以
//        但是,一次读取一行数据的方法时字符串缓冲输入流的特有方法
//        BufferedReader br=new BufferedReader(isr);
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        System.out.println("请输入一个字符串");
        String line=br.readLine();
        System.out.println(line);
        System.out.println("请输入一个数字");
        int num=Integer.parseInt(br.readLine());
        System.out.println(num+100);
//        系统内提供了一个封装好的
        Scanner sc=new Scanner(System.in);
        System.out.print("请输入一个数字:");
        int num2=sc.nextInt();
        System.out.println(num2);


    }
}

4.2、标准输出流

        字节打印流

        字符打印流

字符打印流的构造方法
    PrintWriter (String fileName) 使用指定的文件名创建一个新的PrintWriter而不需要自动执行刷新
    PrintWriter (Writer out , boolean autoFlush) 创建一个新的PrintWriter
        out 字符输出流
        autoFlush一个布尔值,如果真,则println,printf 或者format方法将刷新输出缓冲区

package itheima02;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
/*
字符打印流的构造方法
    PrintWriter (String fileName) 使用指定的文件名创建一个新的PrintWriter而不需要自动执行刷新
    PrintWriter (Writer out , boolean autoFlush) 创建一个新的PrintWriter
        out 字符输出流
        autoFlush一个布尔值,如果真,则println,printf 或者format方法将刷新输出缓冲区

*/

public class PrintStreamDemo {
    public static void main(String[] args) throws IOException {
//    PrintWriter (String fileName) 使用指定的文件名创建一个新的PrintWriter而不需要自动执行刷新
      /*
        PrintWriter pw=new PrintWriter("myOtherStream\\pw.txt");
        pw.print("a");
        pw.write("\r\n");
        pw.write(98);
        pw.write("\r\n");
        pw.println("hello");
//        pw.flush();
        pw.close();
        */

        PrintWriter pw=new PrintWriter(new FileWriter("myOtherStream\\pw.txt"),true);
//        PrintWriter pw=new PrintWriter(new FileWriter("myOtherStream\\pw.txt"),自动刷新);
        pw.println("hello");
        pw.close();

    }
}

案例:复制Java文件打印流改进版

package itheima02;

import java.io.*;

/*
需求:
    把模块目录下的PrintStreamDemo.java复制到模块目录下Copy.java
思路:
    根据数据源创建字符输入流对象
    根据目的地创建字符输出流对象
    读写数据,复制文件
    释放资源
    */
public class CopyJavaDemo {
    public static void main(String[] args) throws IOException {
//根据数据源创建字符输入流对象
        BufferedReader br=new BufferedReader(new FileReader("myOtherStream\\PrintStreamDemo.java"));
        PrintWriter pw=new PrintWriter(new FileWriter("myOtherStream\\Copy.java"),true);
//根据目的地创建字符输出流对象
//        BufferedWriter bw=new BufferedWriter()
        String line;
//读写数据,复制文件
        while((line=br.readLine())!=null)
        {
            pw.println(line);
        }

//释放资源
        pw.close();
        br.close();
    }
}

4.3、对象序列化流、对象反序列化流

对象序列化:就是将对象保存到磁盘中,或者在网络中传输对象

这种机制就是使用一个字节序列表示一个对象,该字节序列包含:对象类型、对象的数据和对象中存储的属性等信息

字节序列写到文件之后,相当于文件中持久保存了一个对象的信息。

对象反序列化:该字节还可以从文件中读取回来,重构对象,对他进行反序列化

实现序列化和反序列化就是要使用对象序列化流和对象反序列化流:

对象序列化流:ObjectOutputStream

  • 将Java对象的原始数据和图形写入OutputStream。可以使用ObjectInputStream读取(重构对象)。可以通过使用流的文件来实现对象的持久存储。如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象
对象序列化流
        构造方法
        ObjectOutputStream(OutputStream out)创建一个写入指定的OutputStream的ObjectOutputStream

序列化对象的方法:
        void writeObject(Object obj)将指定的对象写入ObjectOutputStream

注意:

  • 一个对象要想被序列化,该对象所属的类必须实现Serializable接口
  • Serializable 是一个标记接口,实现该接口,不需要重写任何方法
package itheima03;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

/*
对象序列化流
        构造方法
        ObjectOutputStream(OutputStream out)创建一个写入指定的OutputStream的ObjectOutputStream

序列化对象的方法:
        void writeObject(Object obj)将指定的对象写入ObjectOutputStream
            抛出NotSerializableException 错误时:
                          一个对象要想被序列化,该对象所属的类必须实现Serializable接口
                          Serializable是一个标记接口,实现该接口,不需要重写任何方法
*/
public class ObjectOutputStreamDemo {
    public static void main(String[] args) throws IOException {
        ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("myOtherStream\\oos.txt"));
//       创建对象
        Student s=new Student("科比",41);
//        void writeObject(Object obj)将指定的对象写入ObjectOutputStream
        oos.writeObject(s);
//        释放资源
        oos.close();
    }
}

对象反序列化流:ObjectInputStream

//  ObjectInputStream (InputStream in); 创建从指定的InputStream读取ObjectInputStream
 //Object readObject() 从ObjectInputStream读取一个对象
 

package itheima03;

import java.io.FileInputStream;

import java.io.IOException;
import java.io.ObjectInputStream;

public class ObjectInputStreamDemo {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
//        ObjectInputStream (InputStream in); 创建从指定的InputStream读取ObjectInputStream
        ObjectInputStream ois=new ObjectInputStream(new FileInputStream("myOtherStream\\oos.txt"));
//Object readObject() 从ObjectInputStream读取一个对象
        Object obj=ois.readObject();
        Student s=(Student)obj;
        System.out.println(s.getName()+","+s.getAge());
//      释放资源
        ois.close();
    }
}

用对象序列化流序列化了一个对象后,假如我们修改了对象所属的类文件,读取数据会不会出问题呢?

  • 会出问题:会抛出InvalidClassException异常

如何解决问题。

  • 给对象所属类加一个serialVersionUID

private stasic final long serialVersionUID=42L;

如果一个对象中的某个成员变量的值不想被序列化,又该如何实现?

  • 给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程。

4.4、Propertises

properties是一个Map集合类

可以保存到流中或从流中加载

properties没有泛型

package itheima04;

import java.util.Properties;
import java.util.Set;

public class PropertiesDemo01 {
    public static void main(String[] args){
//        创建集合对象
//没有泛型  Properties<String,String> prop=new Properties<String,String>();
        Properties prop=new Properties();
//        存储元素
        prop.put("itheima001","科比");
        prop.put("itheima002","乔丹");
        prop.put("itheima003","哈登");
        prop.put("itheima004","库里");
//        遍历集合
        Set<Object> keySet=prop.keySet();
        for (Object key:keySet)
        {
            Object value=prop.get(key);
            System.out.println(key+","+value);
        }
    }
}

properties作为集合特有方法

Object setProperty(String Key,String value)设置集合的键和值,都是String类型,底层调用Hash table方法put

String getProperty(String Key)使用此属性列表中指定的键搜索属性

Set<String> StringPropertyName()从该属性列表中返回一个不可能修改的键集,其中对应的值是字符串

package itheima04;

import java.util.Properties;
import java.util.Set;

public class PropertiesDemo02 {
    public static void main(String[] args) {
        Properties prop=new Properties();
//        设置集合的键和值,都是String类型,底层调用的的hiHashtable()的put
        prop.setProperty("001","科比");//直接给定了String类型,put()给的的是Object类型
        prop.setProperty("002","乔丹");
        prop.setProperty("003","哈登");
/*      public synchronized Object setProperty(String key, String value) {
            return put(key, value);
        }
         public synchronized Object put(Object key, Object value) {
            return map.put(key, value);
        }
*/
        System.out.println(prop.getProperty("001"));//输出值  科比
        Set<String> keySet=prop.stringPropertyNames();
        for (String key:keySet)
        {
            String value=prop.getProperty(key);
            System.out.println(key+","+value);

        }



    }
}

Properties和IO流结合的方法:

void load(InputStream inStream) 从输入字节流读取属性列表(键和元素)
void load(Reader readr) 从输入字符流读取属性列表(键和元素对)
void store(ObjectStream out,String comments)    将此属性列表(键和元素)写入Properties表中,以适合于使用load(InputStream)方法的格式写入输出字节流
void store(Writer writer,String comments)   将此属性列表(键和元素)写入Properties表中,
        以适合于使用load(Reader)方法的格式写入输出字符流
package itheima04;
/*void load(InputStream inStream) 从输入字节流读取属性列表(键和元素)
void load(Reader readr) 从输入字符流读取属性列表(键和元素对)
void store(ObjectStream out,String comments)    将此属性列表(键和元素)写入Properties表中,
                                            以适合于使用load(InputStream)方法的格式写入输出字节流
void store(Writer writer,String comments)   将此属性列表(键和元素)写入Properties表中,
        以适合于使用load(Reader)方法的格式写入输出字符流
        */


import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;

public class PropertiesDemo03 {
    public static void main(String[] args) throws IOException{
            myStore();
            myLoad();
    }
//定义一个方法用来文件中的数据读取出来
    private static void myLoad() throws IOException{
        Properties prop=new Properties();
        FileReader fr=new FileReader("myOtherStream\\chunxiao.txt");
//void load(Reader readr) 从输入字符流读取属性列表(键和元素对)
        prop.load(fr);
//        System.out.println(prop);
        fr.close();
        Set<String> keySet=prop.stringPropertyNames();
        for (String key:keySet)
        {
//            String value=keySet.toString();
/*    输出   001,[001, 002, 003, 004]
            002,[001, 002, 003, 004]
            003,[001, 002, 003, 004]
            004,[001, 002, 003, 004]*/
            String value=prop.getProperty(key);
            System.out.println(key+","+value);
        }
    }
//定义一个方法用来将Properties集合中的数据存储到文件中
    private static void myStore() throws IOException {
//       创建一个Properties集合对象
        Properties prop=new Properties();
//        给集合写入数据
        prop.setProperty("001","床前明月光");
        prop.setProperty("002","疑是地上霜");
        prop.setProperty("003","举头望明月");
        prop.setProperty("004","低头思故乡");
//        prop.store(); 先创建Writer 才能将数据存储到集合中
        BufferedWriter br=new BufferedWriter(new FileWriter("myOtherStream\\chunxiao.txt"));
        prop.store(br,"李白的作品");//comments是备注说明    文件会备注: #\u674E\u767D\u7684\u4F5C\u54C1
//        prop.store(br,"李白");//comments是备注说明 文件会备注: #\u674E\u767D
//        prop.store(br,null);//comments是备注说明 文件不会备注:
        br.close();
    }
}

案例:请写程序实现猜数字小游戏只能试玩三次,如果不想玩,提示:游戏试玩已结束,想玩请充值(www.itcast.cn)
思路:
    ①写一个游戏类,里面有一个猜数组的小游戏

package itheima04;
//写一个游戏类,里面有一个才数组得小游戏

import java.util.Random;
import java.util.Scanner;

public class GuessNumber {
    private GuessNumber() {
    }
    public static void start(){
//    要完成猜数字游戏,首先要有一个猜的数字,使用随机数生成该数字,范围1到100
        Random r=new Random();
        int number=r.nextInt(100)+1;
        while(true){
//            使用程序实现才数字,每次均要输入猜测的数字值,需要使用键盘录入实现
            Scanner sc=new Scanner(System.in);
            System.out.println("请输入你要猜的数字:");
            int guessNumber=sc.nextInt();
//比较输入的数字和系统产生的数据,需要使用分支语句,这里使用if  else 根据不同的情况进行猜测结果显示
            if (guessNumber>number){
                System.out.println("你猜的数字"+guessNumber+"大了");
            }else if (guessNumber<number){
                System.out.println("你猜的数字"+guessNumber+"小了");

            }else{
                System.out.println("恭喜你猜中了");
                break;
            }
        }
    }
}


    ②写一个测试类,测试类中有main()方法,main()方法中按照下面得步骤完成
        A:从文件中读取数据到Properties集合,用load()方法实现
                文件已存在:game.txt
                里面有一个数据值:count=0
        B:通过Properies集合获取到玩游戏得次数
        C:判断次数是否到了3次了
                如果到了,给出提示,游戏试玩结束,想玩请充值(www.itcast.cn)
                如果不到3次:
                玩游戏
                次数+1,重新写文件,用Properies的store()方法实现

package itheima04;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;

/*
需求:请写程序实现猜数字小游戏只能试玩三次,如果不想玩,提示:游戏试玩已结束,想玩请充值(www.itcast.cn)
思路:
    写一个游戏类,里面有一个猜数组的小游戏
    写一个测试类,测试类中有main()方法,main()方法中按照下面得步骤完成
        A:从文件中读取数据到Properties集合,用load()方法实现
                文件已存在:game.txt
                里面有一个数据值:count=0
        B:通过Properies集合获取到玩游戏得次数
        C:判断次数是否到了3次了
                如果到了,给出提示,游戏试玩结束,想玩请充值(www.itcast.cn)
                如果不到3次:
                        玩游戏
                        次数+1,重新写文件,用Properies的store()方法实现
*/
public class PropertiesTest {
    public static void main(String[] args) throws IOException {
//    写一个测试类,测试类中有main()方法,main()方法中按照下面得步骤完成
    //    A:从文件中读取数据到Properties集合,用load()方法实现
        Properties prop=new Properties();
        FileReader fr=new FileReader("myOtherStream\\game.txt");
        prop.load(fr);
        fr.close();
        //    文件已存在:game.txt
        //    里面有一个数据值:count=0;
    //    B:通过Properies集合获取到玩游戏的次数
        String count = prop.getProperty("count");
        int number=Integer.parseInt(count);
        //    C:判断次数是否到了3次了
        if (number>=3){
//    如果到了,给出提示,游戏试玩结束,想玩请充值(www.itcast.cn)
            System.out.println("游戏试玩结束,想玩请充值(www.itcast.cn)");
        }else{
            //    如果不到3次:
            //    用GuessNumber类调用start() 继续玩游戏
            GuessNumber.start();
            number++;
            prop.setProperty("count",String.valueOf(number));
            FileWriter fw=new FileWriter("myOtherStream\\game.txt");
            prop.store(fw,null);
            fw.close();
            //    次数+1,重新写文件,用Properies的store()方法实现
        }

    }

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值