Java之IO流学习

来源:互联网 发布:盐和避难所 mac 编辑:程序博客网 时间:2024/05/21 11:21

java之IO流——2

  1. 获取行号的流
  2. 操作基本数据的流
  3. 内存操作流(操作字节数组、字符数组、字符串)
  4. 打印流
  5. 标准输入输出流
  6. 合并流
  7. 对象的序列化流和反序列化流
  8. 集合的Properties与IO流的操作

获取行号的流

LineNumberReader:    1.构造方法LineNumberReader(Reader in) 使用默认输入缓冲区的大小创建新的行编号 reader    2.public int getLineNumber():获取行号    3.public void setLineNumber(intlineNumber):设置起始行号    4.String readLine():读取一行
package com.wy.lnr;import java.io.BufferedWriter;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;import java.io.LineNumberReader;public class LineNumberReaderTest {    public static void main(String[] args) throws IOException {        /*         *  * public int getLineNumber():获取行号         * public void setLineNumber(int lineNumber):设置起始行号         *String readLine():读取一行         *案例:读取文件,每次读取一行打印并且加上行号         */        LineNumberReader lnr = new LineNumberReader(new FileReader("copy.java"));        //FileWriter fw = new FileWriter("copyWithLine.java");        BufferedWriter bw = new BufferedWriter(new FileWriter("copyWithLine.java"));        String s;        int len;        while((s = lnr.readLine())!= null){            bw.write(s);            bw.flush();        }        bw.close();    }}

操作基本数据的流

可以操作基本类型的流对象。
构造方法:
DataInputStream(InputStream in)

DataInputStream:读数据
DataOutputStream:写数据

package com.wy.datastream;import java.io.DataOutputStream;import java.io.FileOutputStream;import java.io.IOException;public class DataOutputStreamTest {    public static void main(String[] args) throws IOException {        DataOutputStream dos = new DataOutputStream(new FileOutputStream("dos.txt"));        dos.writeByte(1);        dos.writeShort(100);        dos.writeInt(1000);        dos.writeLong(10000L);        dos.writeChar(100);        dos.writeFloat(12.34F);        dos.writeDouble(12.34);        dos.writeBoolean(false);    }}////////////////////////////////////////package com.wy.datastream;import java.io.DataInputStream;import java.io.FileInputStream;import java.io.IOException;public class DataStreamTest {    public static void main(String[] args) throws IOException {        /*         * dos.writeByte(1);            dos.writeShort(100);            dos.writeInt(1000);            dos.writeLong(10000L);            dos.writeChar(100);            dos.writeFloat(12.34F);            dos.writeDouble(12.34);            dos.writeBoolean(false);         */        //根据写的顺序进行数据的读        DataInputStream dis = new DataInputStream(new FileInputStream("dos.txt"));        System.out.println(dis.readByte());        System.out.println(dis.readShort());        System.out.println(dis.readInt());        System.out.println(dis.readLong());        System.out.println(dis.readChar());        System.out.println(dis.readFloat());        System.out.println(dis.readDouble());        System.out.println(dis.readBoolean());    }}

运行结果如下图所示:

内存操作流(操作字节数组、字符数组、字符串)

解决临时数据存储的问题。

操作字节数组

ByteArrayInputStream
ByteArrayOutputStream
构造方法:ByteArrayInputStream(byte[] buf)
byte[] toByteArray()
将之前写入内存的流转换成字节数组

package com.wy.bytearraystream;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;public class ByteArrayInputStreamTest {    public static void main(String[] args) throws IOException {        ByteArrayOutputStream baos = new ByteArrayOutputStream();        baos.write("beautfulgirl".getBytes());        byte[] buf = baos.toByteArray();//调用这个方法,将之前写入内存中的数据存储到字节数组中        ByteArrayInputStream bais = new ByteArrayInputStream(buf);        int by;        while ((by=bais.read())!=-1) {            System.out.print((char)by);        }        //关流        bais.close();        baos.close();    }}

操作字符数组

CharArrayReader
CharArrayWrite

操作字符串

StringReader
StringWriter
构造方法:
StringReader(String s)
StringWriter()

package com.wy.stringreader;import java.io.IOException;import java.io.StringReader;import java.io.StringWriter;public class StringReaderOrWriterTest {    public static void main(String[] args) throws IOException {        StringWriter sw = new StringWriter();        sw.write("beautifulgirl");        StringBuffer re = sw.getBuffer();        StringReader sr = new StringReader(re.toString());        int ch;        while ((ch = sr.read()) != -1) {            System.out.println((char)ch);        }        sr.close();        sw.close();    }}

打印流

字节打印流       PrintStream字符打印流       PrintWriter

特点:
A:只能操作目的地,不能操作数据源
B:可以操作任意类型的数据
C:如果启动了自动刷新,能够自动刷新
D:可以操作文件的流

注意:什么流可以直接操作文件?看流对象的API,如果其构造方法同时有File和String类型的参数,就可以直接操作文件。

字节打印流代码示例:

package com.wy.print;import java.io.FileInputStream;import java.io.IOException;import java.io.PrintStream;public class Print {    public static void main(String[] args) throws IOException {        FileInputStream fis = new FileInputStream("copy.java");        PrintStream ps = new PrintStream("printstreamcopy.java");        int ch;        while((ch = fis.read()) != -1){            ps.write(ch);        }        ps.close();        fis.close();    }}

字符打印流示例代码:

package com.wy.print;import java.io.BufferedReader;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;import java.io.PrintWriter;public class PrintWriterTest {    public static void main(String[] args) throws IOException {        BufferedReader br = new BufferedReader(new FileReader("copy.java"));        /*         * 如何启动自动刷新:利用构造         * PrintWriter(OutputStream out, boolean autoFlush)          * PrintWriter(Writer out, boolean autoFlush)         * 如果启用了自动刷新,则只有在调用 println、printf 或 format 的其中一个方法时才可能完成此操作         */         PrintWriter pw = new PrintWriter(new FileWriter("printWritercopy.java"),true);        String line;        while((line = br.readLine())!= null){            pw.println(line);        }        pw.close();        br.close();    }}

标准输入输出流

System类下有这样的两个成员变量:标准输入流:public static final InputStream in标准输出流: public static final PrintStream out

输入流示例代码:

package com.wy.system;import java.io.IOException;import java.io.InputStream;public class SystemIn {    public static void main(String[] args) throws IOException {        /**         * public static final InputStream in         */        //将键盘录入的数据封装在了输入流中        //Scanner sc = new Scanner(System.in);        InputStream is = System.in;        //将键盘录入的数据从输入流中读取出来        int by;        while ((by=is.read())!=-1) {            System.out.print((char)by);        }        //关流        is.close();    }}
package com.wy.system;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;public class SystemIn2 {    public static void main(String[] args) throws IOException {        /**         * 案例2:用IO流实现键盘录入,一次读取一行数据         * InputStream is = System.in;         * InputSreamReader isr = new InputStreamReader(is)         * BufferedReader br = new BufferedReader(isr);          */        //将上面的分析写为一部        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));        //一次读取一行数据        System.out.println("请输入你的姓名");        String name = br.readLine();        System.out.println("请输入你的年龄");        String age = br.readLine();        System.out.println(name+":"+age);    }}

合并流

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

构造:
SequenceInputStream(InputStream s1, InputStream s2) :将s1和s2合并成一个输入流,先读取s1后读取s2

package com.wy.sequence;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.SequenceInputStream;public class SequenceTest {    public static void main(String[] args) throws IOException {        /*         * 合并流:SequenceInputStream类可以将多个输入流串流在一起,合并为一个输入流,因此,该流也被称为合并流。         * 构造:         *SequenceInputStream(InputStream s1, InputStream s2) :         *将s1和s2合并成一个输入流,先读取s1后读取s2         *案例1:         *我要把DataStreamDemo.java和ByteArrayStreamDemo.java写到一个文件Copy.java         *数据源:DataStreamDemo.java         *ByteArrayStreamDemo.java         * 目的地:Copy.java         */        SequenceInputStream sis = new SequenceInputStream(new FileInputStream("copy.java"),new FileInputStream("dos.txt"));        FileOutputStream fos = new FileOutputStream("sequence.txt");        int ch;        while((ch = sis.read())!= -1){            fos.write(ch);        }        fos.close();        sis.close();    }}

对象的序列化流和反序列化流

  • 序列化流:把对象按照流一样的方式写到文件或者在网络中传输。
  • 反序列化流:把文件或者网络中的流对象数据还原对象。

      • ObjectOutputStream:序列化流
        writeObject(Object obj) 将指定的对象写入 ObjectOutputStream。
    • ObjectInputStream:反序列化流
      Object readObject() 从 ObjectInputStream 读取对象。

    注意:如果一个类不是实现Serializable接口无法把实例化,会报异常java.io.NotSerializableException

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

    **如何实现序列化?
    让对象所属类的实现序列化接口。**
    特点:Properties 可保存在流中或从流中加载。

集合的Properties与IO流的操作

含义:Properties 类表示了一个持久的属性集。属性列表中每个键及其对应值都是一个字符串。

Properties的特有功能:
1. A:添加元素
public Object setProperty(String key,String value)
2. B:获取元素
public String getProperty(String key)
public Set stringPropertyNames()

package com.wy.prop;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.util.Properties;import java.util.Set;public class PropertiesTest {    /*     * 我有一个文本文件,我知道数据是键值对形式的,但是不知道内容是什么。     *请写一个程序判断是否有“lisi”这样的键存在,如果有就改变其值为”100”      */    public static void main(String[] args) throws IOException {        FileInputStream fis = new FileInputStream("data.txt");        Properties prop = new Properties();        prop.load(fis);        Set<String> set= prop.stringPropertyNames();        for (String key : set) {            if(key.equals("lisi")){                prop.setProperty("lisi", "100");            }            prop.store(new FileOutputStream("data.txt"), "some comments");        }    }}

猜数字游戏实现、

需求如下:我有一个猜数字小游戏的程序,请写一个程序实现在测试类中只能用5次,
超过5次提示:游戏试玩已结束,请付费。

package com.wy.properties;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.util.Properties;import java.util.Scanner;/**    案例:我有一个猜数字小游戏的程序,请写一个程序实现在测试类中只能用5次,         超过5次提示:游戏试玩已结束,请付费。 * */public class GuessNumber {    public static void main(String[] args) throws IOException {        FileInputStream fis = new FileInputStream("playTimes.txt");        Properties prop = new Properties();        prop.load(fis);        if(Integer.parseInt(prop.getProperty("count"))<=4){            String numstr = prop.getProperty("count");            //System.out.println(numstr);            int num = Integer.parseInt(numstr)+1;            String newNum = num+"";            prop.setProperty("count",newNum);            prop.store(new FileOutputStream("playTimes.txt"), "You have played the game");            guessNum();        }else{            System.out.println("游戏试玩已结束,请付费。");        }    }    private static void guessNum() {        int random = (int) (Math.random()*100+1);        System.out.println(random);        System.out.println("Start");        int guess=0;        Scanner sc = new Scanner(System.in);        while(true){            System.out.println("Please input your guess number:");            guess = sc.nextInt();            if(guess == random){                System.out.println("guess right!");                break;            }            else if(guess > random){                System.out.println("too big");            }            else {                System.out.println("too small");            }        }    }}

最后……

关于java的IO流到此告一段落。IO流学习的重点主要是学习他们的构造方法需要传入什么参数,有时候是一个文件,有时候是一个流;同时转换流在字节流和字符流中间搭建了一个桥梁。字节流可以操作任意类型的流,而字符流只能操作使用记事本打开能看懂的文件。因此在选择的时候,要考虑是什么文件,否则会使得操作的文件部分丢失。

原创粉丝点击