Java基础---IO流三(字节流& 字符流)

2015-04-23

一、转换流(IO流续)

1、编码表概述

     由字符及其对应的数值组成的一张表

编码

把看得懂的变成看不懂的

解码

把看不懂的变成看得懂的

常见的编码表

     ASCII:用7位来表示一个数据

     ISO-8859-1:在西欧使用,用8位来表示一个数据

     GB2312:简体中文,使用2字节来表示一个汉字

     GBK:简体中文

     GB18030:简体中文,替代GBK

     BIG5:繁体中文,台湾,香港使用

     Unicode:国际码,统一码,用2字节表示一个数据,在Java中使用的码就是Unicode

     utf-8:国际码,统一码,表示一个数据,所使用的字节数是变化的,使用1~4位字节表          示一个数据,表示一个汉字时,用3个字节。

字符串中的编码问题

  编码:把看懂的数据转换成 看不懂的数据

  解码:把看不懂的数据  转换成看懂的数据                        

  解码:

  public String(byte[] bytes)用系统平台默认的字符集进行解码指定的 byte 数组

  public String(byte[] bytes,String charsetName) 通过指定的编码表,进行解码指定的byte数组

  编码:

  public byte[] getBytes() 使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。

  public byte[]getBytes(String charsetName) 使用指定的字符集将此String 编码为 byte序列,并将结果存储到一个新的 byte 数组中。

     注:数据的编码操作要字符编码表统一

   2、OutputStreamWriter 字符输出流

     它是Writer的子类,Writer是字符流

     publicOutputStreamWriter(OutputStream out)

     publicOutputStreamWriter(OutputStream out,String charsetName)

     OutputStreamWriter: 转换流

           它是Writer的子类,Writer是字符流   

           作用: 可以将 字节流中的数据,按照指定的编码表进行数据的编码,生产的结果成为了字符流

           字节流 -->  字符流

  OutputStreamWriter: 字符输出流

           构造方法:

           public OutputStreamWriter(OutputStream out)

                              创建使用默认字符编码(gbk)的 OutputStreamWriter。

           public OutputStreamWriter(OutputStream out,StringcharsetName)

               创建使用指定字符集的 OutputStreamWriter。

   3、InputStreamReader 字符输入流

     publicInputStreamReader(InputStream in)

     publicInputStreamReader(InputStream in,String charsetName)

 

4、OutputStreamWriter写数据方法

              public voidwrite(int c) 写入一个字符

              public voidwrite(char[] cbuf) 写入一个字符数组

              public voidwrite(char[] cbuf,int startIndex,int len) 写入字符数组的一部分

              public voidwrite(String str) 写入一个字符串

              public voidwrite(String str,int startIndex,int len) 写入字符串的一部分

 5、字符流操作要注意的问题

              flush()的作用

              flush()和close()的区别

              flush(): 将数据缓冲区中的内容刷新到目的地文件中

              close(): 在关闭之前,执行一次刷洗操作,然后关闭流,释放流所占用的资源

             

              flush()和close()的区别?

                       flush()后,流没有关闭,可以继续读写数据

                       close()后,流关闭了,不能够继续读写数据

6、OutputStreamWriter读数据方法

     public int read()

     public int read(char[]cbuf)

     案例:字符流复制文本文件(copyText.java)

 

7、便捷读写类

     发现上一个版本,使用转换流太麻烦, 有没有简化的方式,应该有

   大多数情况下,我们都是使用平台的默认字节集进行的编解码操作,没有必要使用转         换流,可以使用更简化的流

  

   FileReader:用来读取字符文件的便捷类

   FileWriter:用来写入字符文件的便捷类

   Reader

          |- InputStreamReader

                   |- FileReader

   Writer

          |- OutputStreamWriter

                   |- FileWriter

     举例:便捷类的读写

              //数据源

              FileReader fr =new FileReader("面试题.txt");

              //目的地

              FileWriter fw =new FileWriter("copyText.txt");

              //读数据

              int ch = -1;

              while ((ch =fr.read()) != -1) {

                       //写数据

                       fw.write(ch);

              }

              //关闭流

              fr.close();

              fw.close();

二、BufferedWriter字符缓冲输出流BufferedReader字符缓冲输入流

1、构造方法

     publicBufferedWriter(Writer out)

     public BufferedWriter(Writerout, int size)

2、特殊功能

     BufferedWriter 字符缓冲输出流

                       publicvoid newLine() 根据当前的系统,写一个换行符

     BufferedReader

                       publicString readLine():读取一行字符串, 读取到回车换行结束

                                 当没有获取到有效数据的时候,返回null

     读数据,用readLine()时,如果遍历到空时,返回null。

     代码实现:   

     //读
     public static voidreader() throws IOException {
              //创建流对象
              BufferedReader br= new BufferedReader(new FileReader("bw.txt"));
              //读数据
              String line =null;
              //获取数据,赋值, 判断
              while ((line =br.readLine()) != null) {
                       System.out.println(line);
              }
//           String line =br.readLine();
//           System.out.println(line);
//          
//           line =br.readLine();
//           System.out.println(line);
//          
//           line =br.readLine();
//           System.out.println(line);
             
              //关闭
              br.close();
     }
     //写
     public static voidwriter() throws IOException {
              //创建流对象
              BufferedWriter bw= new BufferedWriter(new FileWriter("bw.txt"));
              //写数据
              for (int i = 1; i<= 10; i++) {
                       bw.write("HelloWorld"+i);
                       bw.newLine();//写一个换行符
                       bw.flush();//刷新数据到目的地
              }
              //关闭
              bw.close();
     }

3、总结:字节与字符流的转换

注意:字符流只能复制文本文件,不能复制图片、视频等文件,而应该用字节流复制这些文件。

举例:

     复制图片,用字节流,正确:

     public static voidmethod1() throws IOException {
     BufferedInputStream bis =new BufferedInputStream(new
                                          FileInputStream("E:\\resource\\IMG_1693.jpg"));
     BufferedOutputStream bos =new
                  BufferedOutputStream(newFileOutputStream("1693.jpg"));
     //读
     byte[] buffer = newbyte[1024];
     int len = -1;
     while ((len =bis.read(buffer)) != -1) {
              //写
              bos.write(buffer,0, len);
     }
     //关闭流
     bis.close();
     bos.close();
    }

复制图片,用字节流,错误:

    public static void method2() throws IOException {
     BufferedReader br = new
     BufferedReader(newFileReader("E:\\resource\\IMG_1693.jpg"));
     BufferedWriter bw = newBufferedWriter(new FileWriter("1693.jpg"));
     //读
     String line = null;
     while ((line =br.readLine()) != null) {
              //写
              bw.write(line);
              bw.newLine();
              bw.flush();
              }
     br.close();
     bw.close();
     }
     }

三、案例

  1、把文本数据复制到ArrayList中

练习:把文本文件中的数据 存储到Arraylist集合中

 

  分析:

                     1:创建字符输入流BufferedReader,用来读取数据

                     2:创建ArrayList集合,用来存储数据

                     3:读取File中的数据

                     4:把数据添加到集合

                     5:遍历集合中的数据

                     6:关闭流

     代码实现:     

          //1:创建字符输入流BufferedReader, 用来读取数据
              BufferedReader br= new BufferedReader(new FileReader("arraylist.txt"));
              //2:创建ArrayList集合,用来存储数据
              ArrayList<String>list = new ArrayList<String>();
              //3:读取File中的数据
              String line =null;
              while ((line =br.readLine()) != null) {
                       //4:把数据添加到集合
                       list.add(line);
              }
              //5:遍历集合中的数据
              for (String s :list) {
                       System.out.println(s);
              }
              //6:关闭流
              br.close();

2、复制单层文件

     数据源:E:\resource无子目录

  目的地:NoDir

  分析:

           1: 封装数据源 (文件夹)

           2: 封装目的地(文件夹)

           3: 获取到数据源所对应的目录中,每一个File对象

           4: 文件的复制

     代码实现:

    public class CopyDir {
     public static voidmain(String[] args) throws IOException {
              //1: 封装数据源 (文件夹)
              File srcPath =new File("E:\\resource无子目录");
              //2: 封装目的地(文件夹)
              File destPath =new File("NoDir");
              //创建目的地文件夹
              destPath.mkdir();
             
              //获取数据源中所有的File对象,得到每个File对象
              File[] files =srcPath.listFiles();
              //3: 获取到数据源所对应的目录中,每一个File对象
              for (File file :files) {
                       //file-- E:\resource无子目录\                  小苹果.flv
                       //dest-- NoDir\                                    小苹果.flv
                       Stringname = file.getName();
                       //4: 文件的复制
                       Filedest = new File(destPath, name);
                       copyFile(file,dest);
              }
             
     }
     //文件的复制
     public static voidcopyFile(File src, File dest) throws IOException {
              //数据源
              BufferedInputStreambis = new BufferedInputStream(new FileInputStream(src));
              //目的地
              BufferedOutputStreambos =new BufferedOutputStream(new FileOutputStream(dest));
              //读
              byte[] buffer =new byte[1024];
              int len = -1;
              while ((len =bis.read(buffer)) != -1) {
                       //写
                       bos.write(buffer,0, len);
              }
              //关闭流
              bis.close();
              bos.close();
     }
}

3、复制多层文件夹

      数据源:E:\resource

           目的地:YesDir

     YesDir

           |- Demo.java

           |- error.wav

           |- 各种专治

                     |- [www-itcast-cn]专治各种疼痛01.mp4

  分析:

  1)封装数据源

  2):封装目的地

   3)创建目的地文件夹

4)获取到数据源中所有的File对象

5)遍历,获取到每一个File对象

 6)  判断当前File对象 是否为 文件夹

          是:

                   文件夹

                             递归,封装好目的地,回到步骤3

          否:        

                   文件

                             文件的复制

                             得到新文件的名称[File对象]

                             开始复制文件

     4、学生成绩的有序存储

           // 1: 创建学生集合对象, TreeSet<Student>
              TreeSet<Student>ts = new TreeSet<Student>(new Comparator<Student>() {
                       @Override
                       publicint compare(Student s1, Student s2) {
                                 //总分
                                 intnum = (int) (s2.sum() - s1.sum());
                                 //语文,数学,英语
                                 intnum2 = (int) ((num == 0) ? (s2.getChineseScore() - s1
                                                   .getChineseScore()): num);
                                 //姓名
                                 returnnum2;
                       }
              });
              // 2:键盘输入数据
              for (int i = 0; i< 3; i++) {
                       Stringname = new Scanner(System.in).nextLine();
                       doublechineseScore = new Scanner(System.in).nextDouble();
                       doublemathScore = new Scanner(System.in).nextDouble();
                       doubleenglishScore = new Scanner(System.in).nextDouble();
                       // 3:创建学生对象,把键盘输入数据 复制给学生对象
                       Students = new Student(name, chineseScore, mathScore, englishScore);
                       // 4: 把学生对象元素添加到集合
                       ts.add(s);
              }
              // 6:创建一个字符输出流对象 BufferedWriter
              BufferedWriter bw= new BufferedWriter(new FileWriter("score.txt"));
              // 5: 遍历,得到每一个元素
              for (Student s :ts) {
                       Stringdata = s.getName() + "\t" + s.getChineseScore() + "\t"
                                          +s.getMathScore() + "\t" + s.getEnglishScore() + "\t"
                                          +s.sum();
                      
                       bw.write(data);
                       bw.newLine();
                       bw.flush();
              }
              //关闭流
              bw.close();

四、行号

   1、设置行号,获得行号的方法

     LineNumberReader 带有行号的字符输入流

 

     public int getLineNumber()获得当前行号。

     public voidsetLineNumber(int lineNumber)设置当前行号。

代码实现:

             //创建流对象
              LineNumberReaderlnr = new LineNumberReader(new FileReader("面试题.txt"));
              lnr.setLineNumber(100);
              //读数据
              String line =null;
              while ((line =lnr.readLine()) != null) {
                       intlineNumber = lnr.getLineNumber();
                       System.out.println(lineNumber+": "+ line);
              }
              //关闭流
              lnr.close();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值