Reader 简单介绍前面说了什么是字节流,今天来看什么是字符流。
字节流与字符流 *** 作的本质区别只有一个:字节流是原生的 *** 作,而字符流是经过处理后的 *** 作。在进行网络数据传输、磁盘数据保存所保存所支持的数据类型只有:字节。
但是无论是字节流还是字符流,所有的基本 *** 作都是一样的,都是基本的步骤,所有学习的方式也是一样的。
1.根据字节流或字符流的子类实例化父类对象 ;
2.进行数据的读取或写入 *** 作
3.关闭流(close())
这里正式来学习
字符流的父类 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(); } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)