Java进阶之----- IO流,字符流

Java进阶之----- IO流,字符流,第1张

Java进阶之----- IO流,字符

前面说了什么是字节流,今天来看什么是字符流。
字节流与字符流 *** 作的本质区别只有一个:字节流是原生的 *** 作,而字符流是经过处理后的 *** 作。在进行网络数据传输、磁盘数据保存所保存所支持的数据类型只有:字节。
但是无论是字节流还是字符流,所有的基本 *** 作都是一样的,都是基本的步骤,所有学习的方式也是一样的。
1.根据字节流或字符流的子类实例化父类对象 ;
2.进行数据的读取或写入 *** 作
3.关闭流(close())
这里正式来学习

Reader 简单介绍
字符流的父类
  InputStreamReader:字符输入流
       InputStreamReader(inputStream in)
          创建一个使用默认字符集的InputStreamReader
       InputStreamReader(InputStream in, String charsetName)
          创建了一个使用命名字符集的InputStreamReader。
InputStreamReader 构造方法 概念
1)使用默认的字符集构造InputStreamReader
流:本质是初始化其实例域的一个变量,并未看到
任何关于字符集的设置。
 public InputStreamReader(InputStream in) {
        super(in);
        try {
            sd = StreamDecoder.forInputStreamReader(in, this, (String)null);
        } catch (UnsupportedEncodingException e) {
           
            throw new Error(e);
        }
    }
2)使用指定的字符集名称构造InputStreamReader流:本质是初始化其实例
域的一个变量,可以发现字符集是初始化方法的第
三个参数
 public InputStreamReader(InputStream in, String charsetName)
        throws UnsupportedEncodingException
    {
        super(in);
        if (charsetName == null)
            throw new NullPointerException("charsetName");
        sd = StreamDecoder.forInputStreamReader(in, this, charsetName);
    }
小练习
public class InputStreamReaderDemo1 {
    public static void main(String[] args) throws IOException {
        //创建字符输入流
//        InputStreamReader isr = new InputStreamReader(new FileInputStream("b4.txt"));
        InputStreamReader isr = new InputStreamReader(new FileInputStream("b4.txt"),"UTF-8");

        //读取数据
        //int read()
        //读一个字符
//        System.out.println((char) isr.read());
        int b =0;
        while ((b=isr.read())!=-1){
            System.out.print((char)b);
        }

        //释放资源
        isr.close();


    }
}
方法

这里只看两种方法

InputStreamReader读取数据的方法:
        public int read():一次读取一个字符
        public int read(char[] cbuf):一次读取一个字符数组
public class InputStreamReaderDemo2{
	public static void main(String[] args){
		//创建字符输入流的对象
		InputStreamReader isr = new InputStreamReader(new FileInputStream("b4.txt"),"UTF-8")
	}
	int c = 0;
	while((c = isr.read())!=-1){
		System.out.println((char)c);
	}

	//public int read(char[] cbuf):一次读取一个字符数组
	char[] chars = new char[1024];
	int length = 0;
	while ((length = isr.read())!=-1){
		System.out.println(length);
            System.out.println(new String(chars, 0, length));
	}
	//释放资源
        isr.close();
}
writer
Writer:(java提供 *** 作字符流的父类)
            OutputStreamWriter 字符输出流(字符转换流)
                OutputStreamWriter(OutputStream out)
                    创建一个使用默认字符编码的OutputStreamWriter。
                OutputStreamWriter(OutputStream out, String charsetName)
                    创建一个使用命名字符集的OutputStreamWriter。

OutputStreamWriter OutputStreamWriter流构造函数 概念
 1)利用输出流构建默认字符编码的OutputStreamWriter流:本质是初始化StreamEncoder对象
      private final StreamEncoder se;
 
      public OutputStreamWriter(OutputStream out) {
        super(out);
        try {
            se = StreamEncoder.forOutputStreamWriter(out, this, (String)null);
        } catch (UnsupportedEncodingException e) {
            throw new Error(e);
        }
    }
2)通过指定的字符编码构建OutputStreamWriter流:本质是初始化StreamEncoder对象但是指定了字符编码
    public OutputStreamWriter(OutputStream out, String charsetName)
        throws UnsupportedEncodingException
    {
        super(out);
        if (charsetName == null)
            throw new NullPointerException("charsetName");
        se = StreamEncoder.forOutputStreamWriter(out, this, charsetName);
    }
小练习
public class OutputStreamWriterDemo {
    public static void main(String[] args) throws IOException {
        //创建字符流输出对象
        //如果目标文件不存在,会自动创建
//        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("b2.txt"));

        //OutputStreamWriter(OutputStream out, String charsetName)
        //创建一个使用命名字符集的OutputStreamWriter。
        OutputStreamWriter osw2 = new OutputStreamWriter(new FileOutputStream("b3.txt"), "GBK");

        //往文件中写入数据
//        osw.write("我爱中国");
        osw2.write("我爱家乡");

        //释放资源
//        osw.close();
        osw2.close();

    }
}
方法
 OutputStreamWriter写数据的5个方法:
        public void write(int c)
        public void write(char[] cbuf)
        public void write(char[] cbuf,int off,int len)
        public void write(String str)
        public void write(String str,int off,int len)
public class OutputStreamWriterDemo2 {
    public static void main(String[] args) throws IOException {
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("b4.txt"));

        //写数据
        //public void write(int c)
        osw.write(99);
        osw.flush();

        //public void write(char[] cbuf)
        //一次写一个字符数组
        char[] chars = {'a','b','c','d','e'};
        osw.write(chars);
        osw.flush();

        //public void write(char[] cbuf,int index,int length)
        //一次写入字符数组的一部分
        osw.write(chars, 1, 3);
        osw.flush();

        //public void write(String str)
        //一次写入一个字符串
        osw.write("刘生发真帅!");
        osw.flush();

        //public void write(String str,int off,int len)
        //一次写入字符串的一部分
        osw.write("刘生发真帅!",0,3);
        osw.flush();


        //释放资源
        osw.close();


    }
}
案例
 把当前项目目录下的a.txt内容复制到当前项目目录下的b.txt中

        数据源:
            a.txt -- 读取数据 -- 字符输入流(字符转换流) -- InputStreamReader

        目的地:
            b.txt -- 写出数据 -- 字符输出流(字符转换流) -- OutputStreamWriter
public class FileCopyDemo3 {
    public static void main(String[] args) throws IOException {
        //创建字符输入流对象
        InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));

        //创建字符输出流对象
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("b.txt"));

        //读写数据
//        //一次读写一个字符
//        int c = 0;
//        while ((c = isr.read()) != -1) {
//            osw.write(c);
//            osw.flush();
//        }


        //一次读写一个字符数组
        char[] chars = new char[1024];
        int length = 0;
        while ((length = isr.read(chars)) != -1) {
            osw.write(chars, 0, length);
            osw.flush();
        }


        //释放资源
        osw.close();
        isr.close();


    }
}

转换流
    字符流(转换流) =  字节流 + 编码表

    加密:把能看懂转成看不懂的(编码)
    String -- byte[]

    解密:把看不懂的转成能看懂的(解码)
    byte[] -- String

    编码的格式于解码的格式要一致,否则解码出来的内容你可能看不懂
import java.nio.charset.Charset;
import java.util.Arrays;

public class ZhuanHuanliuDemo {
    public static void main(String[] args) throws Exception {
        //查看当前的编码格式
        System.out.println(Charset.defaultCharset());

        //加密:把能看懂转成看不懂的(编码)
        //        String -- byte[]
        String s = "kayleigh真帅!";

        //byte[] getBytes(Charset charset)
        //使用给定的charset将该String编码为字节序列,将结果存储到新的字节数组中。
//        byte[] b1 = s.getBytes("UTF-8");
//        System.out.println(Arrays.toString(b1));
        byte[] b1 = s.getBytes("Unicode");
        System.out.println(Arrays.toString(b1));



        //解密:把看不懂的转成能看懂的(解码)
        //byte[] -- String
        //String(byte[] bytes, Charset charset)
        //构造一个新的String由指定用指定的字节的数组解码charset 。
//        String s1 = new String(b1,"UTF-8");
        String s1 = new String(b1,"Unicode");
        //Unicode两个字节组成一个中文字符
        System.out.println(s1);


    }
}

缓冲区类(高效类) 字符缓冲输出
    字节缓冲输出流:
        BufferedOutputStream

    字节缓冲输入流:
        BufferedInputStream
              
               问题:
    我们在使用字节流读取中文的时候,一个一个字节的读取,发现强转之后,出现了我们看不懂的字符
public class BufferedOutputStreamDemo1 {
    public static void main(String[] args) throws IOException {
        //BufferedOutputStream(OutputStream out)
        //创建一个新的缓冲输出流,以将数据写入指定的底层输出流。

//        FileOutputStream fos = new FileOutputStream("b1.txt");
//        BufferedOutputStream bos = new BufferedOutputStream(fos);

        //开发中推荐该方式创建
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("b1.txt"));

        //往文件中写入数据
        //void write(byte[] b)
        bos.write("大数据,yyds;朱佳乐真帅!".getBytes());
        bos.flush();


        //释放资源
        //关闭的时候,关闭之前也对缓冲区进行了一次刷新
        //关闭之后bos不能用了
        bos.close();

//        bos.write("数加科技".getBytes());
//        //IOException: Stream Closed
//        bos.flush();


    }
}

字符缓冲输入流
BufferedReader:字符缓冲输入流


BufferedReader(Reader in)
    创建使用默认大小的输入缓冲区的缓冲字符输入流。
public class BufferedReaderDemo1 {
    public static void main(String[] args) throws IOException {
        //创建字符缓冲输入流对象
//        BufferedReader br = new BufferedReader(
//                new InputStreamReader(
//                        new FileInputStream("a.txt")));

        //简化写法
        BufferedReader br = new BufferedReader(new FileReader("a.txt"));

        //第一种:一次只读一个字符
//        int c = 0;
//        while ((c = br.read()) != -1) {
//            System.out.print((char) c);
//        }

        //第二种:一次读取一个字符数组
        char[] chars = new char[1024];
        int length = 0;
        while ((length=br.read(chars))!=-1){
            System.out.println(new String(chars,0,length));
        }


        //释放资源
        br.close();


    }
}

字符流为了高效读写,也提供了相对应的字符缓冲流
BufferedWriter:字符缓冲输出流
BufferedReader:字符缓冲输入流

BufferedWriter:字符缓冲输出流、
将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入。
可以指定缓冲区大小,或者可以接受默认大小。 默认值足够大,可用于大多数用途
public class BufferedWriterDemo1 {
    public static void main(String[] args) throws IOException {
        //创建字符缓冲输出流
        //BufferedWriter(Writer out)
        //创建使用默认大小的输出缓冲区的缓冲字符输出流。
//        BufferedWriter bw = new BufferedWriter(
//                new OutputStreamWriter(
//                        new FileOutputStream("b5.txt")));

        //简化写法
        BufferedWriter bw = new BufferedWriter(new FileWriter("b5.txt"));

        //写数据
        bw.write("hello");
        bw.write("rn");
        bw.write("world");
        bw.write("rn");
        bw.write("java");
        bw.write("rn");
        bw.write("hadoop");


        bw.flush();


        //释放资源
        bw.close();


    }
}

    字符缓冲流的特殊方法:
        BufferedWriter:
            public void newline()
         throws IOException写一行行分隔符。
         行分隔符字符串由系统属性line.separator定义,
         并不一定是单个换行符(' n')字符。

        BufferedReader:
            public String readLine()
            throws IOException读一行文字。
            一行被视为由换行符(' n'),回车符(' r')中的任何一个或随后的换行符终止。
public class BufferedWriterDemo2 {
    public static void main(String[] args) {
//        write();

        read();

    }

    public static void read(){
        //创建字符缓冲输入流
        BufferedReader br = null;
        try {
            br = new BufferedReader(new FileReader("b6.txt"));
//            String s = br.readLine();
//            System.out.println(s);
//
//            String s1 = br.readLine();
//            System.out.println(s1);
//
//            String s2 = br.readLine();
//            System.out.println(s2);

            //用循环改进读取数据,因为我们不知道一个文件到底有多少行,我们用while循环
            //如果已达到流的末尾,则为null
            String line = null;
            while ((line=br.readLine())!=null){
                System.out.println(line);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    public static void write() {
        //创建字符缓冲输出流
        BufferedWriter bw = null;
        try {
            bw = new BufferedWriter(new FileWriter("b6.txt"));
            //往文件中写入数据
            for (int i = 0; i < 10; i++) {
                bw.write("大数据" + i);
//                bw.write("rn");
                bw.newline();

                bw.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                bw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }
}

简化写法
    由于我们正常做字符流的处理的时候,一般都不会去刻意传入编码,用的都是默认的编码
    基本数不会去指定。
    而通过学习完转换流之后,发现,名字有点长,所以Java就提供了子类给我们使用

    字符流 = 字节流 + 编码表
    OutputStreamWriter  =  FileOutputStream + 编码表(Unicode)
    InputStreamReader = FileInputStream + 编码表(Unicode)

    字符转换流的简化写法:
        字符输出流:
            FileWriter
        字符输入流:
            FileReader

    复制文件
public class FileCopyDemo5 {
    public static void main(String[] args) throws IOException {
        //创建字符输入流对象
//        InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));

        //创建简化后的字符输入流对象
        FileReader fr = new FileReader("a.txt");

        //创建简化后的字符输出流对象
        FileWriter fw = new FileWriter("c1.txt");

        //第一种方式:一次读写一个字符
//        int c = 0;
//        while ((c=fr.read())!=-1){
//            fw.write(c);
//            fw.flush();
//        }

        //第二种方式:一次读写一个字符数组
        char[] chars = new char[1024];
        int length = 0;
        while ((length=fr.read(chars))!=-1){
            fw.write(chars, 0, length);
            fw.flush();
        }

        //释放资源
        fw.close();
        fr.close();


    }
}

案例
	使用高效字符流复制文件
public class FileCopyDemo7 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("b.txt"));

        BufferedWriter bw = new BufferedWriter(new FileWriter("ceshi2.txt"));

        long start = System.currentTimeMillis();
        //一次读取一个字符数组
        char[] chars = new char[1024];

        int length = 0;
        while ((length = br.read(chars)) != -1) {
            bw.write(chars, 0, length);
            bw.flush();
        }

        long end = System.currentTimeMillis();

        System.out.println("总耗费时间:" + (end - start));

        //释放资源
        bw.close();
        br.close();

    }
}
    字符缓冲流特殊功能复制文件:
        数据源:
            a.txt -- 读取数据 -- 字符输入流 -- InputStreamReader -- FileReader -- BufferedReader

        目的地:
            b7.txt -- 写出数据 -- 字符输出流 -- OutputStreamWriter -- FileWriter -- BufferedWriter
public class FileCopyDemo8 {
    public static void main(String[] args) throws IOException {
        //创建字符缓冲输入流对象
        BufferedReader br = new BufferedReader(new FileReader("a.txt"));

        //创建字符缓冲输出流对象
        BufferedWriter bw = new BufferedWriter(new FileWriter("b7.txt"));

        String line = null;
        while ((line=br.readLine())!=null){
            bw.write(line);
            bw.newline();
            bw.flush();
        }

        //释放资源
        bw.close();
        br.close();

    }
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5680968.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存