首页 » Java » IO流(二)

IO流(二)

原文 http://blog.csdn.net/promiseend/article/details/78544001

2017-11-16 02:01:16阅读(254)

转换流 读取键盘录入

需求一:读取一个键盘录入的数据,并打印在控制台上。
键盘本身就是一个标准的输入设备,对于java而言,对于这种输入设备都有对应的对象,这些对象在System类中。
默认的输入设备和输出设备都不需要关闭流,这个流会随着系统的出现而出现,随着系统的消失而消失。

public class ReadKey {
    public static void main(String[] args) throws IOException {
        readKey();
    }
//  读取一个键盘录入的数据,并打印在控制台上
    public static void readKey() throws IOException {
        InputStream in=System.in;
        int ch=in.read();//read()是一种阻塞式方法
        System.out.println(ch);
        int ch1=in.read();//阻塞式方法
        System.out.println(ch1);
        int ch2=in.read();//阻塞式方法
        System.out.println(ch2);    
/*      A   输入的A
        65  输出 A的ASCII码值
        13  输出的'\r'的ASCII码值
        10  输出的'\n'的ASCII码值
        */
/*      默认的输入设备和输出设备都不需要关闭流
        in.close();//不需要关,这个流会随着系统的出现而出现,随着系统的消失而消失
        //关了会发生异常:java.io.IOException: Stream closed
        InputStream in2=System.in;
        int ch3=in2.read();*/
    }
}

需求二:获取用户键盘录入的数据,并将数据变成大写显示在控制台上。如果用户输入的是over 结束键盘录入。

思路:
1.因为键盘录入的只读取一个字节,要判断是否是over,需要将读取到的字节拼成字符串
2.那就需要一个容器 StringBuilder
3.在用户回车之前将录入的数据变成字符串判断即可。
public class ReadKey {
    public static void main(String[] args) throws IOException {
        readKey2();
    }
    public static void readKey2() throws IOException {
        //1.创建容器
        StringBuilder sb=new StringBuilder();
        //2.获取键盘读取流
        InputStream in=System.in;
        //3.定义变量记录读取到的字节,并循环获取
        int ch=0;
        while((ch=in.read())!=-1){
//          在存储之前需要判断是否是换行标记,因为换行标记不存储
            if(ch=='\r')
                continue;
            if(ch=='\n'){
                String temp=sb.toString();
                if("over".equals(temp))
                    break;
                System.out.println(temp.toUpperCase());
                sb.delete(0, sb.length());
            }
            else
            //将读取到的字节存储到StringBuilder中
            sb.append((char)ch);
        }
    }
}
转换流

在读取键盘录入的第二个需求中,我们读取键盘输入的字节,但是需要将判断输入的是否是”over”,即需要将读取到的字节拼成字符串。在需求二里我们自己构建了一个从字节到字符的桥梁。在java中,已经定义好了这样一个桥梁:
转换流
InputStreamReader:字节流到字符流的桥梁。可使用指定的charset将要写入流中的字节解码成字符。它使用的字符集可以由名称指定或显式给定,否则接受平台默认的字符集。(解码)
OutputStreamWriter:字符流到字节流的桥梁。可使用指定的charset将要输出流的字符编码成字节。(编码)

同样的需求用转换流来做:获取用户键盘录入的数据,并将数据变成大写显示在控制台上。如果用户输入的是over 结束键盘录入。

public class TransStreamDemo {
    public static void main(String[] args) throws IOException {
        //字节流
        InputStream in=System.in;
        //转换流
        InputStreamReader isr=new InputStreamReader(in);
        //字符流
        BufferedReader bufr=new BufferedReader(isr);
        //字节流
        OutputStream out=System.out;
        //转换流
        OutputStreamWriter osw=new OutputStreamWriter(out);
        //字符流
        BufferedWriter bufw=new BufferedWriter(osw);
        String line=null;
        while((line=bufr.readLine())!=null){
            if("over".equals(line))
                break;
//          System.out.println(line.toUpperCase());
        /*  osw.write(line.toUpperCase());
            osw.flush();*/
            bufw.write(line.toUpperCase());
            bufw.newLine();
            bufw.flush();
        }
    }
}

更加简洁的代码如下:

public class TransStreamDemo{
    public static void main(String[] args) throws IOException {
        keyToConsole();
    }
    public static void keyToConsole() throws IOException {
        BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out));
        String line=null;
        while((line=bufr.readLine())!=null){
            if("over".equals(line))
                break;
            bufw.write(line.toUpperCase());
            bufw.newLine();
            bufw.flush();
        }
    }
}

字符本身来自于字节,但里面都是由纯文本的数据组成,用字符流操作起来非常方便,用几个需求的实现来感受一下:

package p1.transstream.demo;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
public class TransStreamDemo2 {
    public static void main(String[] args) throws IOException {
        /*1.需求:将键盘录入的数据写入到一个文件中  demo1
         * 
         * 2.需求:将一个文本文件内容显示在控制台上demo2
         * 
         * 3.需求:将一个文本文件中的内容复制到另一个文件中  demo3
         * 只需要改变流的源和目的
         * */
//      demo1();
//      demo2();
        demo3();
    }
    public static void demo3() throws IOException {
        BufferedReader bufr=new BufferedReader(new InputStreamReader(new FileInputStream("a.txt")));
        BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("b.txt")));
        String line=null;
        while((line=bufr.readLine())!=null){
            if("over".equals(line))
                break;
            bufw.write(line.toUpperCase());
            bufw.newLine();
            bufw.flush();
        }
    }
    public static void demo2() throws IOException {
        BufferedReader bufr=new BufferedReader(new InputStreamReader(new FileInputStream("a.txt")));
        BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out));
        String line=null;
        while((line=bufr.readLine())!=null){
            if("over".equals(line))
                break;
            bufw.write(line.toUpperCase());
            bufw.newLine();
            bufw.flush();
        }
    }
    public static void demo1() throws IOException {
        BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("a.txt")));
        String line=null;
        while((line=bufr.readLine())!=null){
            if("over".equals(line))
                break;
            bufw.write(line.toUpperCase());
            bufw.newLine();
            bufw.flush();
        }
    }
}
流的基本操作规律 IO流的操作规律

流对象太多,开发时不知道用哪个对象合适,这时要寻求流的基本操作规律。
想要知道开发时用到哪些对象。只需要通过四个明确即可:
1.明确源和目的(汇)

源:InputStream、Reader
目的: OutputStream、Writer

2.明确数据是否是纯文本数据

源:
|---是纯文本:Reader
|---否:InputStream
目的:
|---是纯文本:Writer
|---否:OutputStream

到这里,就可以明确需求中具体要使用哪个体系。

3.明确具体的设备

源设备:
    |---硬盘:File
    |---键盘:System.in
    |---内存:数组
    |---网络:Socket流
目的设备:
    |---硬盘:File
    |---控制台:System.out
    |---内存:数组
    |---网络:Socket流

4.是否需要其他额外功能

1.是否需要高效(缓冲区):
    是,就加上buffer
2.是否需要转换(转换流)
规律的体现

需求1:复制一个文本文件。

1.明确源和目的。
源:InputStream Reader
目的:OutputStream Writer
2.是否是纯文本:
是
源:Reader
目的:Writer
3.明确具备设备
    源:
        硬盘:File
    目的:
        硬盘:File
    FileReader fr=new FileReader("a.txt");
    FileWriter fw=new FileWriter("b.txt");
4.需要额外功能吗?
 需要高效
 BufferedReader bufr=new BufferedReader(new FileReader("a.txt"));
 BufferedWriter bufw=new BufferedWriter(new FileWriter("b.txt"));

需求2:读取键盘录取信息,并写入到一个文件中。

1.明确源和目的。
    源:InputStream Reader
    目的:OutputStream Writer
2.是否是纯文本:是
    源:Reader
    目的:Writer
3.明确具备设备
源:
    键盘:System.in
目的:
    硬盘:File
    InputStream in=System.in;
    FileWriter fw=new FileWriter("b.txt");//这样做可以完成,但是麻烦。将读取的字节数据转成字符串,再由字符流转换为字节流
4.需要额外功能:
转换:
InputStreamReader isr=new InputStreamReader(System.in);
FileWriter fw=new FileWriter("b.txt");
高效:
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw=new BufferedWriter(new FileWriter("b.txt"));

需求三:将一个文本文件数据显示在控制台上。

1.明确源和目的。
    源:InputStream Reader
    目的:OutputStream Writer
2.是否是纯文本:是
    源:Reader
    目的:Writer
3.明确具备设备
源:
    硬盘:File
目的:
    控制台:System.out
FileReader fr=new FileReader("a.txt");
OutputStream out=System.out; 
4.是否需要额外功能:
需要,转换:
FileReader fr=new FileReader("a.txt");
OutputStreamWriter osw=new OuputStreamWriter(System.out);
需要,高效:
BufferedReader bufr=new BufferedReader(new FileReader("a.txt"));
BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out));

需求四:读取键盘录入数据,显示在控制台上。

1.明确源和目的。
    源:InputStream Reader
    目的:OutputStream Writer
2.是否是纯文本:是
    源:Reader
    目的:Writer
3.明确具备设备
源:
    键盘:System.in
目的:
    控制台:System.out
InputStream fr=System.in;
OutputStream out=System.out; 
4.是否需要额外功能:
需要转换,因为都是字节流,但是操作的却是文本数据,所以使用字符流操作起来更为便捷
InputStreamReader isr=new InputStreamReader(System.in); 
OutputStreamWriter osw=new OutputStreamWriter(System.out);
需要,高效:
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out));
转换流的编码解码

需求五:将一个中文字符串数据按照指定的编码表写入到一个文本文件中。
按照“四个明确”分析:
1.目的 OutputStream Writer
2.是纯文本 Writer
3.设备:硬盘File
FileWriter fw=new FileWriter(“a.txt”);
fw.write(“你好”);

注意:既然需求中已经明确了指定编码表的动作。那就不可以使用FileWriter,因为FileWriter内部是使用默认的本地码表(这里是gbk)。
只能使用其父类。OutputStreamWriter。
OutputStreamWriter接收一个字节输出流对象。既然是操作文件,那么该对象应该是FileOutputStream
OutputStreamWriter osw=new OutStreamWriter(new FileOutputStream("a.txt"),charsetName);

4.需要额外功能

高效:
BufferedWriter bufw=new BufferedWriter(new OutStreamWriter(new FileOutputStream("a.txt"),charsetName));

指定编码表的写出与读入代示例:

public class TransStreamDemo3 {
    public static void main(String[] args) throws IOException {
//      writeText();
//      writeText_2();
//      writeText_3();
//      readText_1();
        readText_2();
    }
    public static void readText_2() throws IOException {
        InputStreamReader isr=new InputStreamReader(new FileInputStream("u8_1.txt"),"UTF-8");
        char[] buf=new char[1024];
        int len=isr.read(buf);
        String str=new String(buf,0,len);
        System.out.println(str);
        isr.close();
    }
    public static void readText_1() throws IOException {
        FileReader fr=new FileReader("gbk_1.txt");
        char[] buf=new char[1024];
        int len=fr.read(buf);
        String str=new String(buf,0,len);
        System.out.println(str);
        fr.close();
    }
    public static void writeText_3() throws IOException {
        OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("u8_1.txt"),"UTF-8");
        osw.write("你好");
        osw.close();
    }
    public static void writeText_2() throws IOException {
        OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("gbk_3.txt"),"GBK");
        FileWriter fw=new FileWriter("gbk_1.txt");
        /*这两句代码功能是等同的。
        FileWriter:其实就是转换流指定了本机默认码表的体现。而且这个转换流的子类对象,可以方便操作文本文件。
                    简单说:操作文本的字节流+本机默认的编码表
                    这是按照默认码表来操作文件的便捷类
        如果操作文本文件需要明确具体的编码,必须用转换流,不能再用FileWriter。*/
        osw.write("你好");
        osw.close();
    }
    public static void writeText() throws IOException {
        FileWriter fw=new FileWriter("gbk_1.txt");
        fw.write("你好");
        fw.close();
    }

最新发布

CentOS专题

关于本站

5ibc.net旗下博客站精品博文小部分原创、大部分从互联网收集整理。尊重作者版权、传播精品博文,让更多编程爱好者知晓!

小提示

按 Ctrl+D 键,
把本文加入收藏夹