Java---IO加强(2)

转换流

★转换流功能1:充当字节流与字符流之间的桥梁

需求:模拟英文聊天程序,要求:

(1) 从键盘录入英文字符,每录一行就把它转成大写输出到控制台;

(2) 保存聊天记录到字节流文件。

要求1的设计分析:

1)需要从键盘接收录入,得用System.in,它是字节输入流InputStream;

2)需要处理字符,可以自己把字节强转成字符,也可以用字符流;

3)需要类似readLine的功能,而这个方法在字符流BufferedReader中有(而且该类有缓冲增速)。

综上,采用转换流把字节流转成字符流处理比较合理,即使用InputStreamReader

要求2的设计分析:

1)需要把字符数据按行保存到字节流文件 ;

2)字符流采用BufferedWriter比较合适,因为它有newLine方法且能实现高效;

3)字节流文件,得采用FileOutputStream。

综上,采用转换流把字符流转成字节流处理比较合理,即使用OutputStreamWriter

代码实现:

package io.transfer;

import java.io.BufferedReader;
import java.io.BufferedWriter;
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 TranStreamDemo {

    public static void main(String[] args) throws IOException {
        //输入
        InputStream in = System.in;
        InputStreamReader isr = new InputStreamReader(in);
        BufferedReader br = new BufferedReader(isr);

        //输出
        OutputStream out = new FileOutputStream("chat.txt");
        OutputStreamWriter osw = new OutputStreamWriter(out);
        BufferedWriter bw = new BufferedWriter(osw);

        String line = null;
        while( (line=br.readLine())!=null){
            if("over".equals(line)){
                //养成好的代码习惯:调用String中的方法时,把常量字符串放在前面,防止变量为null而导致异常
                break;
            }
            System.out.println( line.toUpperCase() );
            bw.write(line);
            bw.newLine();
            bw.flush();//字符流是带缓冲的,必须刷缓冲
        }
    }

}

转换流

(InputStreamReader和OutputStreamWriter)

★转换流功能2:字符编码转换

采用FileWriter以默认方式编码

FileOutputStream+默认编码表

采用转换流以默认方式编码

OutputStreamWriter + FileOutputStream + 默认编码表

采用转换流以指定编码方式编码

OutputStreamWriter + FileOutputStream +指定编码表

采用转换流以指定编码方式解码

InputStreamReader + FileInputStream +指定编码表

代码实现:

package io.transfer;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class TranStreamDemo2 {

    public static void main(String[] args) {
        try {
            //readTextDecoding1();
            //readTextDecoding2();
            writeTextEncoding();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void writeTextEncoding() throws IOException {
        //第一种: FileWriter+默认编码表
        FileWriter fw = new FileWriter("files\\w_utf-8.txt");//该文件的编码由平台(如MyEclipse或dos窗口)定,不一定是utf-8
        fw.write("每天进步一点点...");
        fw.close();

        //第二种: OutputStreamWriter+默认编码表
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("files\\w_utf-8_2.txt"));//该文件的编码由平台(如MyEclipse或dos窗口)定,不一定是utf-8
        osw.write("第天进步一点点...");//牛耳
        osw.close();

        //第三种: OutputStreamWriter+指定编码表
        OutputStreamWriter osw2 = new OutputStreamWriter(new FileOutputStream("files\\w_utf-8_3.txt"),"utf-8");//该文件的编码一定是utf-8,因为是我们自己指定的
        osw2.write("第天进步一点点...");
        osw2.close();

    }

    private static void readTextDecoding1() throws IOException {
        FileReader fr = new FileReader("files\\utf-8.txt");//采用默认编码表解码
        char[] cbuf = new char[10];
        int len=0;
        while( (len=fr.read(cbuf))!=-1){
            String str = new String(cbuf,0,len);
            System.out.print(str);
        }
        fr.close();
    }

    private static void readTextDecoding2() throws IOException {
        //InputStreamReader isr = new InputStreamReader(new FileInputStream("files\\gbk.txt"));//如果不指定编码表,则是采用默认的

        //用转换流自己指定解码表----只要文件的编码表和这里指定的解码表相同,就不会出现乱码
        //InputStreamReader isr = new InputStreamReader( new FileInputStream("files\\gbk.txt"), "gbk"); //ok
        //InputStreamReader isr = new InputStreamReader( new FileInputStream("files\\utf-8.txt"), "gbk");//乱码
        InputStreamReader isr = new InputStreamReader( new FileInputStream("files\\utf-8.txt"), "utf-8");//ok
        char[] cbuf = new char[20];
        int len = isr.read(cbuf);
        String str = new String(cbuf,0,len);
        System.out.println(str);
        isr.close();
    }

}

打印流

★打印流的特点:

1)只有输出没有输入。PrintStream是字节打印流,PrintWriter是字符打印流。

2)能够方便地打印各种数据“值表示形式”,提供了一系列的打印功能(只有它有,其它流都没有。)

3)和其他输出流不同,它永远不会抛出IOException异常(构造方法除外),异常内部解决且设置了内部标志。

4)可创建具有自动刷新的功能,可使用带换行符的println()方法。

5)(在构造方法中)可以指定字符集编码的。

★关于打印流的自动刷新

autoFlush - boolean 变量;如果为 true,则 println、printf 或 format 方法将刷新输出缓冲区。

* —其实是因为这几个方法中帮我们调用了out.flush()。

代码实现:

//演示PrintStream类的自动刷新功能

package io.print;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;

/**
 *
 * @author 陈浩翔
 *
 * 2016-4-24
 */

//演示PrintStream类的自动刷新功能
public class PrintStreamDemo {
    public static void main(String[] args) {
        try {
            demo1();
            demo2();
            for(int i=0;i<10;i++){
                System.out.println(i);
            }
            //屏幕终端不会有输出的,因为运行了demo2();
            //把System.out的输出目的地从屏幕更改到日志文件了

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    //把System.out的输出目的地从屏幕更改到日志文件
    private static void demo2() throws IOException {
        FileOutputStream font = new FileOutputStream("log.txt");
        PrintStream out = new PrintStream(font,true);
        System.setOut(out);
    }

    private static void demo1() throws IOException {
        PrintStream out =new PrintStream("print.txt");
        //out.write()只写入一个字节(二进制的8位)的信息,如果参数大于一个字节的范围,
        //那么实际上只会写入最后一个字节的数据
        out.write(97);
        out.write(353);
        //最后一个字节是97,因此写入的是一个字符‘a‘----写入的是值的表现形式

        System.out.write(353);//输出‘a‘
        System.out.flush();

        out.println(345);//把参数转换成字符串输出
        //上一句等价于out.write( String.valueOf(i) )

        //※总之,PrintStream中用write()输出的是字节数据且每次只输出一个字节,而print()输出的是数据的值的表现形式即转换成字符串输出。
        //JSP中的out对象就是这种类型。要输出字节数据如图片声明等二进制格式则必须用write(),而输出页面数据(字符)则要用print()或println()

    }

}

//演示PrintWriter类的自动刷新功能

package io.print;

import java.io.IOException;
import java.io.PrintWriter;

/**
 *
 * @author 陈浩翔
 *
 * 2016-4-24
 */

//演示PrintWriter类的自动刷新功能
public class PrintStreamDemo2 {
    public static void main(String[] args)   {
        demo1();
        try {
            demo2();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void demo1() {
        //默认不自动刷新的
        PrintWriter out  =new PrintWriter(System.out);
        out.print("Hello World");//不会自动刷新
        out.println("Hello World");//不会自动刷新
        out.flush();//手动刷新
    }

    private static void demo2() throws IOException {
        //设置自动刷新的
        PrintWriter out = new PrintWriter(System.out,true);
        out.print("Hello World");//不会自动刷新
        out.println("Hello World");//会----因为println()内部调用了out.flush()
        out.print("Hello3 \n");//不会
        out.print("Hello3 \r\n");//不会
        out.printf("%s", "Hello4");//会

        /*总之:
         * autoFlush - boolean 变量;如果为 true,则 println、printf 或 format 方法将刷新输出缓冲区。
         * ---其实是因为这几个方法中帮我们调用了out.flush()。
         */
    }

}

IO包中的其他流

下面三个都是内存数组:

★字节数组流

ByteArrayInputStream与ByteArrayOutputStream

★字符数组流

CharArrayReader与CharArrayWriter

★字符串流

StringReader 与 StringWriter

1、用于操作字节数组的流对象,其实它们就是对应设备为内存的流对象。

2、该流的关闭是无效的,因为没有调用过系统资源。

3、按照流的读写思想操作数组中元素。

★序列流

SequenceInputStream  ——对多个流进行合并

将多个流进行逻辑串联(合并变成一个流,操作起来很方便,因为多个源变成了一个源)

IO流知识点小结

流是用来处理数据的。

处理数据时,一定要先明确数据源与数据目的地(数据汇)。

数据源可以是文件、键盘或者其他流。

数据目的地可以是文件、显示器或者其他流。

流只是在帮助数据进行传输,并对传输的数据进行处理,比如过滤处理、转换处理等。

★ IO流体系

使用要点:看顶层(父类共性功能),用底层(子类具体对象)。

命名规律:

每个子类的后缀名都是所属体系的父类的名称,很容易区分所属的体系。

而且每一个子类前缀名都是该子类对象的功能体现。

掌握IO流体系的要点和规律,开发时设计与查找相应的类就容易多了

时间: 2024-10-12 05:07:21

Java---IO加强(2)的相关文章

java IO之输入流——InputStream

java的基本输入流是java.io.InputStream,该抽象类定义了输入流的基本输入操作方法,实现自该抽象类的子类都有定义自己的数据源,例如ByteArrayInputStream的构造函数指定了ByteArrayInputStream输入流的数据源必须是一个字符数组.这就可以有多种不同的数据源,包括:字符数组.String对象.文件."管道".一个由其他种类的流组成的序列... 1 public ByteArrayInputStream(byte buf[]) {} 2 3

Hive报错 Failed with exception java.io.IOException:java.lang.IllegalArgumentException: java.net.URISyntaxException: Relative path in absolute URI: ${system:user.name%7D

报错信息如下 Failed with exception java.io.IOException:java.lang.IllegalArgumentException: java.net.URISyntaxException: Relative path in absolute URI: ${system:user.name%7D 解决方法: 编辑 hive-site.xml 文件,添加下边的属性 <property> <name>system:java.io.tmpdir<

java.io.IOException: No space left on device 错误

今天碰到比较奇怪的问题: 7/05/14 19:20:24 INFO util.Utils: Fetching http://192.168.31.160:33039/jars/spark_study_java-0.0.1-SNAPSHOT-jar-with-dependencies.jar to /tmp/spark-446068a4-aaa4-4277-b009-908bf0d4ecac/executor-dcc3175b-7d19-4485-81e1-bf31a83a66b4/spark-

【java】io流之字节输入流:java.io.InputStream类及子类java.io.FileInputStream

1 package 文件操作; 2 3 import java.io.File; 4 import java.io.FileInputStream; 5 import java.io.IOException; 6 import java.io.InputStream; 7 8 public class TestInputStream { 9 public static void main(String[] args) throws IOException { 10 File file=new F

java io 学习

1,io 体系 在整个Java.io包中最重要的就是5个类和一个接口.5个类指的是File.OutputStream.InputStream.Writer.Reader:一个接口指的是Serializable.掌握了这些IO的核心操作那么对于Java中的IO体系也就有了一个初步的认识了. Java.io包中定义了多个流类型类实现输入输出的功能,从不同的角度可以分为: ~按照数据流方向的不同可以分为输入流和输出流. ~按照按照数据处理单位的不同可以分为字节流和字符流. 如下几张图可以直观的描述io

Java IO流 探险

Java的IO流使用了一种装饰器设计模式,它将IO流分为底层节点流和上层处理流.本篇重点在如何访问文件与目录.如何以二进制格式和文本格式来读写数据.对象序列化机制.还有Java7的"NIO.2". 装饰设计模式:当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有的功能,并提供加强功能.那么自定义的该类称为装饰类. 装饰类通常会通过构造方法接收被装饰的对象.并基于被装饰的对象的功能,提供更强的功能. IO的方式通常分为:BIO(同步阻塞).NIO(同步非阻塞).AIO

Play生产模式下java.io.FileNotFoundException那点事

之前”用Scala+Play构建地理数据查询接口”那篇文章里,用到的数据是json格式的文本文件area.json,存放在conf/jsons文件夹下.最开始是放在public/文件夹下,在线上准生产模式下运行: activator dist 得到mosquito-1.0.zip压缩包,解压后: 去/bin目录下运行mosquito脚本报错: java.io.FileNotFoundException 然后就去解压的mosquito-1.0/看发现并没有public文件夹,由此可见public文

keytool 错误: java.io.FileNotFoundException: 拒绝访问

keytool 错误: java.io.FileNotFoundException: 拒绝访问 打开命令行,切换到D:\AndroidStudioProjects\MyApplication\app目录 keytool 在JDK的/bin目录下,比如:/opt/jdk/bin 用以下的命令生成一个证书: keytool -genkey -alias android.key -keyalg RSA -validity 20000 -keystore android.key 老是报如题的错误: 后来

Java IO详解(转)

IO是Java及众多编程语言很重要的一块,同时很多程序的瓶颈和耗时操作也都在IO这块. 一.简介 IO操作面临很多问题,信息量的巨大,网络的环境等等,因为IO不仅仅是对本地文件.目录的操作,有时对二进制流.还有一部分是网络方面的资源,所以多种原因直接造成IO操作无疑是耗时且复杂多变的.Java对IO的支持是个不断的演变过程,经过了很多的优化,直到JDK1.4以后,才趋于稳定,在JDK1.4中,加入了nio类,解决了很多性能问题,虽然我们有足够的理由不去了解关于Java IO以前的情况,但是为了学

Java IO操作:合并流

合并流:把两个文件合并在一起. 主要操作的是内容. 定义: public class SequenceInputStreamextends InputStream 方法摘要: 操作步骤: 1,分别建立两个FileInputStream实例对象,用于输出指定两个文件. 2,建立一个FileOutputStream实例,用于合并写入两个文件. 2,通过SequenceInputStream类,把两个文件的内容合并起来,放到这个类实例流中. 3,把SequenceInputStream实例的内容读取出