Java之IO流学习

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值