Java学习笔记之IO补充

时间:2022-03-24 12:35:59

随着对文件学习的深入,我们开始学习到了关于对IO流的一些操作,主要是通过以下几个类进行学习的
1.LineNumberReader
public class LineNumberReaderextends BufferedReader
跟踪行号的缓冲字符输入流。
对于它的使用主要用到两个方法:
* public int getLineNumber():获取行号
* public void setLineNumber(int lineNumber):设置起始行号
具体使用如下:
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;

    /**
案例:读取文件,每次读取一行打印并且加上行号
*
*/

public class LineNumberReaderDemo {
public static void main(String[] args) throws IOException {
LineNumberReader lnr = new LineNumberReader(new FileReader("copy.txt"));
int lineNumber = lnr.getLineNumber();
System.out.println(lineNumber);

// lnr.setLineNumber(3);

String line;
while((line = lnr.readLine()) != null){
System.out.println(lnr.getLineNumber() + ": " + line);
}
}
}

2.操作基本数据类型的流

  • 可以操作基本类型的流对象。
  • DataInputStream:读数据
  • DataOutputStream:写数据

  • 案例:给流中写基本类型的数据,并且读取
    注意:
  • 读写顺序必须一致,否则数据有问题。
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;

    /**
    案例:给流中写基本类型的数据,并且读取
    注意:

    • 读写顺序必须一致,否则数据有问题。
      *
      */

    public class DataOutputStreamDemo {
    public static void main(String[] args) throws IOException {
    //写数据
    write();
    read();
    }

    private static void read() throws IOException {
    //DataInputStream:读数据
    //创建对象:public DataInputStream(InputStream in)
    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());

    //关流
    dis.close();
    }

    private static void write() throws IOException {
    //public DataOutputStream(OutputStream out)
    DataOutputStream dos = new DataOutputStream(new FileOutputStream("dos.txt"));

    //给流关联的文件中写入基本类型的数据
    dos.writeByte(20);
    dos.writeShort(200);
    dos.writeInt(2000);
    dos.writeLong(20000L);

    dos.writeChar(97);
    dos.writeFloat(12.34F);
    dos.writeDouble(23.34);
    dos.writeBoolean(true);

    //关流
    dos.close();
    }

    }
    3.内存操作流:
    解决临时数据存储的问题。
    此类类有
    A.操作字节数组:ByteArrayInputStream,ByteArrayOutputStream
    B.操作字符数组:CharArrayReader,CharArrayWrite
    C.操作字符串:StringReader,StringWriter
    以ByteArrayInputStream类为例,它包含一个内部缓冲区,该缓冲区包含从流中读取的字节。内部计数器跟踪read方法要提供的下一个字节。关闭ByteArrayInputStream无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException。
    ByteArrayOutputStream类实现了一个输出流,其中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray() 和toString()获取数据。关闭ByteArrayOutputStream无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException。
    其他类和他们类似。
    4.打印流
    字节打印流 PrintStream 为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。它还提供其他两项功能。与其他输出流不同,PrintStream 永远不会抛出 IOException;而是,异常情况仅设置可通过 checkError方法测试的内部标志。另外,为了自动刷新,可以创建一个 PrintStream;这意味着可在写入 byte 数组之后自动调用 flush 方法,可调用其中一个 println 方法,或写入一个换行符或字节 (‘\n’)。PrintStream打印的所有字符都使用平台的默认字符编码转换为字节。在需要写入字符而不是写入字节的情况下,应该使用 PrintWriter 类。

    字符打印流       PrintWriter

    特点:
    A:只能操作目的地,不能操作数据源
    B:可以操作任意类型的数据
    C:如果启动了自动刷新,能够自动刷新
    D:可以操作文件的流
    下面用一个复制文件的案例来证明一下PrintStream和PrintWriter的方便之处:
    import java.io.BufferedReader;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.PrintWriter;

    public class CopyJavaDemo {
    public static void main(String[] args) throws IOException {
    BufferedReader br = new BufferedReader(new FileReader("d://TestTime.java"));
    PrintWriter pw = new PrintWriter(new FileWriter("TestTime2.java"), true);

    String len;
    while((len = br.readLine()) != null){
    pw.println(len);//1.写数据 2.换行 3.刷新
    }

    br.close();
    pw.close();
    }
    }

    5.标准输入输出流
    System类下有这样的两个成员变量:

    标准输入流:
    public static final InputStream in

    案例1:利用标注输入流进行键盘录入,录入后读取流并打印在控制台
    import java.io.IOException;
    import java.io.InputStream;

    public class SystemIn {
    public static void main(String[] args) throws IOException {
    //Scanner sc = new Scanner(System.in);底层还是输入流
    InputStream is = System.in;//将键盘录入封装成输入流

    int by;
    while((by = is.read()) != -1){
    System.out.print((char)by);
    }

    is.close();
    }
    }

    案例2:用IO流实现键盘录入,一次读取一行数据
    分析:
    InputStream is = System.in;
    BufferedReader是字符缓冲流,是对字符流进行高效操作的
    所以,参数必须是字符类型
    而我们现在有的是字节类型的流
    请问:怎么办呢?转换流
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;

        public class SystemInDemo2 {
    public static void main(String[] args) throws IOException {
    //用io流实现键盘录入

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

    System.out.println("请输入姓名");
    String name = br.readLine();
    System.out.println(name);
    System.out.println("请输入年龄");
    String age = br.readLine();
    System.out.println(age);
    br.close();
    }
    }

    标准输出流:
    public static final PrintStream out

    案例:解析输出语句System.out.println(“helloworld”);
    import java.io.PrintStream;

    public class SystemOutDemo {
    public static void main(String[] args) {
    PrintStream ps = System.out;
    ps.println(true);//等同于System.out.println();
    }
    }
    1. 合并流:
      SequenceInputStream类可以将多个输入流串流在一起,合并为一个输入流,因此,该流也被称为合并流。

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

    1. Properties(查看api实现map接口本质是一个map集合)
      7.1
      Properties:Properties 类表示了一个持久的属性集。属性列表中每个键及其对应值都是一个字符串。
      特点:Properties 可保存在流中或从流中加载。
      案例:使用map集合的put方法给集合中存储数据并且遍历

    7.2
    Properties的特有功能:
    A:添加元素
    public Object setProperty(String key,String value)
    B:获取元素
    public String getProperty(String key)
    public Set stringPropertyNames()
    案例:使用它的特有功能添加元素并遍历

    7.3
    可以和IO流进行结合使用:
    把文件中的数据加载到集合中。注意:文件中的数据必须是键值对象形式的(例如:张杰=谢娜)。
    public void load(InputStream inStream)
    public void load(Reader reader)
    案例:创建一个键值对文件,将文件中的键值对加载到集合中,输出集合

    把集合中的数据存储到文本文件中,并且是按照键值对形式存储的。
    public void store(OutputStream out,String comments)
    public void store(Writer writer,String comments)
    案例:将创建的键值对集合加载到文件中

案例:我有一个猜数字小游戏的程序,请写一个程序实现在测试类中只能用5次,
超过5次提示:游戏试玩已结束,请付费。
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;

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

public class PropertiesDemo {
public static void main(String[] args) throws Exception{
Properties prop = new Properties();
prop.load(new FileReader("count.txt"));

Integer number = Integer.valueOf(prop.getProperty("count"));
number++;
if(number>2){
System.out.println("试玩结束,请付费!");
System.exit(0);
}else{
prop.setProperty("count", String.valueOf(number));
prop.store(new FileWriter("count.txt"), null);
System.out.println("第"+number+"次试玩");
GuessNumber.startGame();
}
}
}