黑马程序员——java基础—IO流(二)

来源:互联网 发布:万能扫描仪软件免费版 编辑:程序博客网 时间:2024/05/05 21:21

——- android培训java培训、期待与您交流! ———-

打印流概述:

字节流打印流   PrintStream

字符流打印流   PrintWriter

打印流的特点:

     A:只有写数据,没有读取数据。只能操作目的地,不能操作数据源。

B:可以操作任意类型的数据。

C:如果启动了自动刷新,能够自动刷新。

D:可以操作文件的流。

那些流对象是可以直接操作文本文件的呢?

FileInputStream

FileOutputStream

FileReader

FileWriter

printStream

printWriter

看API,查流对象的构造方法,如果同时有File类型和String类型的参数,一般来说就是可以直接操作文件的。

流对象:

   基本流:就是能直接读写文件

   高级流:在基本流基础上提供了一些其他功能;

1.      可以操作任意类型的数据:

Print()

Pritln()

2.      启动自动刷新:

printWriter   pw = new PrintWriter(new FileWriter(“a.txt:” ,true)

还是调用println()的方法才可以;

这个时候不仅仅自动刷新了,还实现了数据的换行;

 Println() 等价于:

 Write();

 newLine();

 flush();

 

打印流复制文本文件;

  // 以前的版本      // 封装数据源      // BufferedReader br = new BufferedReader(newFileReader(      // "DataStreamDemo.java"));      // // 封装目的地      // BufferedWriter bw = new BufferedWriter(newFileWriter("Copy.java"));      //      // String line = null;      // while ((line = br.readLine()) != null) {      // bw.write(line);      // bw.newLine();      // bw.flush();      // }      //      // bw.close();      // br.close();       // 打印流的改进版      // 封装数据源      BufferedReader br = new BufferedReader(new FileReader(            "DataStreamDemo.java"));      // 封装目的地      PrintWriter pw = new PrintWriter(new FileWriter("Copy.java"), true);           String line = null;      while((line=br.readLine())!=null){         pw.println(line);      }           pw.close();      br.close();   }

IO流标准输入输出流概述和输出语句的本质:

System类中的两个成员变量:

  Public  static final  InputStream  in  “标准“输入流;

  Public  static final  PrintStream  out  “标准”输出流;

inputStream  is= System.in;

PrintStream ps= System.out;

System.in 标准输入流,是从键盘获取数据的

键盘录入数据:

      A:main方法的args接收参数;

      B:Scanner()

        Scanner  sc = newScanner(System.in);

        String  s = sc.nextLine();

        Int  x= sc.nextInt();

      C:通过字符缓冲流包装标准输入流实现;

 BuffereReader br = new BufferedReader(new InputStreamReader(system.in);

public static void main(String[] args) throwsIOException {      // //获取标准输入流      // InputStream is = System.in;      // //我要一次获取一行行不行呢?      // //行。      // //怎么实现呢?      // //要想实现,首先你得知道一次读取一行数据的方法是哪个呢?      // //readLine()      // //而这个方法在哪个类中呢?      // //BufferedReader      // //所以,你这次应该创建BufferedReader的对象,但是底层还是的使用标准输入流      // // BufferedReader br = new BufferedReader(is);      // //按照我们的推想,现在应该可以了,但是却报错了      // //原因是:字符缓冲流只能针对字符流操作,而你现在是字节流,所以不能是用?      // //那么,我还就想使用了,请大家给我一个解决方案?      // //把字节流转换为字符流,然后在通过字符缓冲流操作      // InputStreamReader isr = newInputStreamReader(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 i = Integer.parseInt(br.readLine());      line = br.readLine();      int i = Integer.parseInt(line);      System.out.println("你输入的整数是:" + i);   }

随机访问流:

RandomAccessFile类不属于流,是Object类的子类。

但它融合了InputStream和OutputStream的功能。

支持对随机访问文件的读取和写入;

 

 PublicRandAccessFile(String name,String mode)

 第一个参数是文件路径,

第二个参数是操作文件的模式;

private static void read() throws IOException {      // 创建随机访问流对象      RandomAccessFile raf = new RandomAccessFile("raf.txt", "rw");       int i = raf.readInt();      System.out.println(i);      // 该文件指针可以通过 getFilePointer方法读取,并通过 seek 方法设置。      System.out.println("当前文件的指针位置是:" + raf.getFilePointer());       char ch = raf.readChar();      System.out.println(ch);      System.out.println("当前文件的指针位置是:" + raf.getFilePointer());       String s = raf.readUTF();      System.out.println(s);      System.out.println("当前文件的指针位置是:" + raf.getFilePointer());       // 我不想重头开始了,我就要读取a,怎么办呢?      raf.seek(4);      ch = raf.readChar();      System.out.println(ch);   }    private static void write() throws IOException {      // 创建随机访问流对象      RandomAccessFile raf = new RandomAccessFile("raf.txt", "rw");       // 怎么玩呢?      raf.writeInt(100);      raf.writeChar('a');      raf.writeUTF("中国");       raf.close();   }}

合并流:

SequencelnputStream概述:

SequenceInputStream类可以将多个输入流串流在一起,合并为一个输入流,因此,该流也称为合并流;

SequenceInputStream的构造方法:

SenquenceInputStream(InputStream  s1 , InputStream  s2)

SequenceInputStream(Enumeration <? ExtendsInputStream>e)

1.txt + b.txt = c.txt;

 InputStream s1 = new FileInputStream("a.txt");   InputStream s2 = new FileInputStream("b.txt");   SequenceInputStream sins = new  SequenceInputStream(s1,s2);   BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("c.txt"));   //如何读写   byte[]  buy = new byte[1024];   int len = 0;   while((len = sins.read(buy))!= -1 ){       bos.write(buy,0 ,len);   }   bos.close();   sins.close();  }

合并流读取多个文件的内容复制到一个文件中;

SequenceInputStream (Enumeration  e)

通过简单的回顾我们知道了Enumeration是 Vector中的一个方法的返回值类型;

Enumeration<E>  elements()

Vector<InputStream>  v = new Vector<InputStream>();  InputStream s1 = new FileInputStream("a.txt");  InputStream s2 = new FileInputStream("b.txt");  InputStream s3 = new FileInputStream("c.txt");  v.add(s1);  v.add(s2);  v.add(s3);  Enumeration<InputStream>          en =v.elements();   SequenceInputStream sins = new SequenceInputStream(en);   BufferedOutputStream bos= new BufferedOutputStream(new FileOutputStream("c.txt"));   //读写文件件;   byte[]  bys = new byte[1024];   int len = 0;   while((len= sins.read(bys)) != -1){      bos.write(bys,0 ,len);   }    bos.close();   sins.close();        }

序列化流:

序列化流:把对象按照流一样的方式存入文本文件或者在网络中传输。对象——流数据(ObjectOutputStream)

反序列化流:把文本文件中的流对象数据或者网络中的流对象数据还原成对象。流数据———(ObjectInputStream)

 

Public final void writeObject(Object  obj);

 

NotSerializableException没有序列化接口接口;

 

类通过实现java.io.Serializable接口以启动其序列化功能,未实现此接口的类将无法使其任何状态序列化或反序列化;

该接口居然没有任何方法,类似于这种没有方法的接口被称为标记接口;

 

public static void main(String[] args) throws IOException,ClassNotFoundException {   //由于我们要对对象进行序列化,所以我们先定义一个类   //序列化数据其实就是把对象写到文本文件;write();read();   }   private static void read() throws IOException, ClassNotFoundException {      // TODOAuto-generated method stub   //创建反序列化对象ObjectInputStreamois = new ObjectInputStream(new FileInputStream("oos.txt"));   //还原对象;   Object obj=ois.readObject();   //释放资源   ois.close();   System.out.println(obj);             }   private static void write() throws IOException {      // TODOAuto-generated method stub   ObjectOutput oos =  new  ObjectOutputStream(new FileOutputStream("oos.txt"));     //创建对象   person p = new person("dephi",25);   oos.writeObject(p);   //释放资源;   oos.close();       }  类的序列化:NotSerializableException:未序列化异常 * * 类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。 * 该接口居然没有任何方法,类似于这种没有方法的接口被称为标记接口。 * * java.io.InvalidClassException: * cn.itcast_07.Person; local classincompatible: * stream classdesc serialVersionUID =-2071565876962058344, * local class serialVersionUID = -8345153069362641443 * * 为什么会有问题呢? *    Person类实现了序列化接口,那么它本身也应该有一个标记值。 *    这个标记值假设是100。 *    开始的时候: *    Person.class-- id=100 *    wirte数据: oos.txt -- id=100 *    read数据: oos.txt -- id=100 * *    现在: *    Person.class-- id=200 *    wirte数据: oos.txt -- id=100 *    read数据: oos.txt -- id=100 * 我们在实际开发中,可能还需要使用以前写过的数据,不能重新写入。怎么办呢? * 回想一下原因是因为它们的id值不匹配。 * 每次修改java文件的内容的时候,class文件的id值都会发生改变。 * 而读取文件的时候,会和class文件中的id值进行匹配。所以,就会出问题。 * 但是呢,如果我有办法,让这个id值在java文件中是一个固定的值,这样,你修改文件的时候,这个id值还会发生改变吗? * 不会。现在的关键是我如何能够知道这个id值如何表示的呢? * 不用担心,你不用记住,也没关系,点击鼠标即可。 * 你难道没有看到黄色警告线吗? * * 我们要知道的是: *    看到类实现了序列化接口的时候,要想解决黄色警告线问题,就可以自动产生一个序列化id值。 *    而且产生这个值以后,我们对类进行任何改动,它读取以前的数据是没有问题的。 * * 注意: *    我一个类中可能有很多的成员变量,有些我不想进行序列化。请问该怎么办呢? *    使用transient关键字声明不需要序列化的成员变量 */public class Person implements Serializable {   private static final long serialVersionUID = -2071565876962058344L;    private String name;    // private int age;    private transient int age;    // int age;    public Person() {      super();   }    public Person(String name, int age) {      super();      this.name = name;      this.age = age;   }    public String getName() {      return name;   }    public void setName(String name) {      this.name = name;   }    public int getAge() {      return age;   }    public void setAge(int age) {      this.age = age;   }    @Override   public String toString() {      return "Person [name=" + name + ",age=" + age + "]";   }}

Properties集合

Properties概述:

Properties属性集合类,是一个可以和IO流相结合的使用的集合类。

Properties可以保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串;

是Hashtable子类,说明是一个Map集合;

Propertiesprop = new Properties();   //添加元素;     prop.put("001" , "hello");    prop.put("002", "world");      prop.put("003", "java");    //遍历集合    Set<Object> set = prop.keySet();    for(Object key : set){       Objectvalue = prop.get(key);       System.out.println(key + "----"+ value);    }      }}

Properties的特殊功能使用:

特殊功能:

publicObject setProperty(String key,String value):添加元素

publicString getProperty(String key):获取元素

publicSet<String> stringPropertyNames():获取所有的键的集合

 

   

   // 创建集合对象      Properties prop = new Properties();       // 添加元素      prop.setProperty("张三", "30");      prop.setProperty("李四", "40");      prop.setProperty("王五", "50");       // public Set<String> stringPropertyNames():获取所有的键的集合      Set<String> set =prop.stringPropertyNames();      for (String key : set) {         String value = prop.getProperty(key);         System.out.println(key + "---" + value);      }   } 

Properties和IO流的结合使用:

这里的集合必须是Properties集合;

Public void  load(Reader reader):把文件中的数据读取到集合中

Public void  store(Writer writer,  String comments) ;把集合中的数据存储到文件

 

  

 private static void myStore() throws IOException {      //创建集合对象   Properties prop = new Properties();   prop.setProperty("刘洋", "23");   prop.setProperty("刘明宇", "20");   prop.setProperty("江代欣", "22");     Writer w = new FileWriter("me.txt");   prop.store(w, "hellworld");   w.close();     }

 private static void myload() throws IOException {      // TODOAuto-generated method stub      Properties prop = new Properties();      Reader r = new FileReader("oos.txt");      prop.load(r);      r.close();      System.out.println("prop"+ prop);           }

案例:判断文件中是否有指定的键如果有就修改值得案列:

 Properties prop = new Properties();   Reader r = new FileReader("me.txt");    prop.load(r);   r.close();   //遍历集合//Set<String>set = prop.stringPropertyNames();  拿到所有的键     Set<Object>  st= prop.keySet();     for(Object obj : st){        String s = (String) obj;        if("刘明宇".equals(s)){           prop.setProperty(s, "2525");           break;        }     }      //把集合中的数据重新存储到文件中     Writer w= new FileWriter("me.txt");     prop.store(w, "九月");       w.close();}

 



0 0
原创粉丝点击