[关闭]
@w460461339 2016-11-16T07:08:19.000000Z 字数 10379 阅读 852

Java学习Day10(字符流 以及N多例子)

Java基础


今天学习的是字符流。在学习字符流之前,我们还是把File和字节流再理一遍。

1.Review

File类
其中储存的是文件或者文件夹的抽象路径名。即,无论这个文件存在不存在,都可以写出来。
通过它,可以创建文件/文件夹,获取类型,获取名称,获取文件夹内所有的文件等等操作。总而言之,它是针对文件这个整体进行操作,不涉及文件具体储存内容的修改。

字节流
字节流有两种,输入流和输出流。
输出流:

OutputStream(抽象类)→FileOutputStream(实现子类)或BufferedOutputStream(高速流)

输入流:

InputStream(抽象类)→FileInputStream(实现子类)或者BufferedInputStream(高速流)

构造时,利用File(包装好的文件路径)或者String(字符串表示的文件路径)都行。
字节流能够实现对文件内部数据的操作。注意,此时就没文件夹什么事了,全部都是对文件的。比如往文件内部写入数据,从文件内部读出数据,将文件A的数据复制给文件B等等。所以,字节流是针对文件内部数据的。

2.字符流

字符流=字节流+编码表
因此,最基本的字符流是通过字节流与制定编码表得到的。

2.1 字符转换流

按照前文的定义,字符流=字节流+编码表。字符转换流就是负责这一操作的。同理,这也有字符输入流和字符输出流之分。

2.1.1字符输出转换流

Writer(抽象类)→OutputStreamWriter(具体实现类)
OutputStreamWriter的构造方法需要一个字节输出流OutputStream的对象以及用String表示指定的编码表,比如“GBK”,"UTF-8"等等。

其中,可以通过write方法往文件中写入数据
void write(int c) 等于 void write(char c);
void write(String st);
void write(char[] chas,int start,int off);

2.1.2字符输入转换流

Reader(抽象类)→InputStreamWriter(具体实现类)
InputStreamWriter的构造方法需要一个字节输入流InputStream的对象以及用String表示指定的编码表,比如“GBK”,"UTF-8"等等。

其中,可以通过read方法来读取。read方法有两种形式
int read();//一次读取一个字符
int read(char[] chs);//一次读取一个字符数组

2.1.3代码演示
  1. import java.io.FileInputStream;
  2. import java.io.FileOutputStream;
  3. import java.io.IOException;
  4. import java.io.InputStreamReader;
  5. import java.io.OutputStreamWriter;
  6. public class ZifuStream {
  7. public static void main(String[] args)throws IOException {
  8. //指明读取和写入都是按照GBK的编码表来读入和写入
  9. InputStreamReader isr=new InputStreamReader(
  10. new FileInputStream("a.txt"), "GBK");
  11. OutputStreamWriter osw=new OutputStreamWriter(
  12. new FileOutputStream("b.txt"), "GBK");
  13. //利用一次读取一个字符数组来读取
  14. int len=0;
  15. char[] chs=new char[1024];
  16. while((len=isr.read(chs))!=-1){
  17. osw.write(chs, 0, len);
  18. }
  19. osw.flush();//刷新后数据才进文件
  20. osw.close();//关闭时自动刷新
  21. isr.close();
  22. }
  23. }
2.2 简化字符流

之前那个字符转化流在可以自己指定编码表的同时,名字太长了,用起来不方便。因此诞生了简化的字符流。
简化字符输出流:

Writer(抽象类)→OutputStreamWriter(具体实现类)→FileWriter(具体实现类)

简化字符输入流:

Reader(抽象类)→InputStreamWriter(具体实现类)→FileReader(具体实现类)

这两个类除了构造函数可以直接利用String类型或者File类型来读取文件,并且采用系统默认的编码表以外,和他们的父类没有区别。

  1. import java.io.FileReader;
  2. import java.io.FileWriter;
  3. import java.io.IOException;
  4. public class MyFileWriter_Reader {
  5. public static void main(String[] args) throws IOException {
  6. FileReader isr=new FileReader("a.txt");//默认编码表
  7. FileWriter osw=new FileWriter("b.txt");
  8. int len=0;
  9. char[] chs=new char[1024];
  10. while((len=isr.read(chs))!=-1){
  11. osw.write(chs, 0, len);
  12. }
  13. osw.flush();
  14. osw.close();
  15. isr.close();
  16. }
  17. }
2.3 高效字符流

高效字符输入流:

Reader(抽象类)→BufferedReader(实现类)
其构造方法需要用Reader的具体实现类作为参数

高效字符输出流:

Writer(抽象类)→BufferedWriter(实现类)
其构造方法需要用Writer的具体实现类作为参数

其输入和输出的基本用法和之前的基本流完全一样,下面演示其特有用法

  1. import java.io.BufferedReader;
  2. import java.io.BufferedWriter;
  3. import java.io.FileReader;
  4. import java.io.FileWriter;
  5. import java.io.IOException;
  6. public class BufferedDemo {
  7. public static void main(String[] args) throws IOException{
  8. //Reader与Writer的具体实现类作为构造函数的参数
  9. BufferedReader br=new BufferedReader(
  10. new FileReader("a.txt"));
  11. BufferedWriter bw=new BufferedWriter(
  12. new FileWriter("b.txt"));
  13. //初始化字符串为null
  14. String st=null;
  15. //reanLine按行读入,遇到换行符停止,因此不会读入换行符。
  16. //在复制时需要自行写入
  17. //读到末尾时,返回null
  18. while((st=br.readLine())!=null){
  19. bw.write(st);//按行写入
  20. bw.newLine();//人工换行
  21. bw.flush();//刷新
  22. }
  23. bw.close();//关了
  24. br.close();//关了
  25. }
  26. }

3.练习

3.1 把ArrayList中的数据存储到文本文件中。

分析:
A:构建ArrayList,存入数据
B:利用字符流输出。构建BufferedWriter高效字符输出流。
C:遍历ArrayList,将每次结果输出到txt文件中。
D:利用BufferedWriter的newLine,换行

  1. import java.io.BufferedWriter;
  2. import java.io.File;
  3. import java.io.FileWriter;
  4. import java.io.IOException;
  5. import java.util.ArrayList;
  6. public class CopyArraytoTxtDemo {
  7. public static void main(String[] args) throws IOException{
  8. //添加数据
  9. ArrayList<String> myarray=new ArrayList<String>();
  10. myarray.add("hello");
  11. myarray.add("world");
  12. myarray.add("java");
  13. //两种输出方式,FileWriter基本输出流
  14. //FileWriter fw=new FileWriter(new File("c.txt"));
  15. //BufferedWriter高效输出流
  16. BufferedWriter bw=new BufferedWriter(new FileWriter(new File("d.txt")));
  17. //遍历
  18. for(String s:myarray){
  19. bw.write(s);
  20. bw.newLine();//换行
  21. bw.flush();//刷新
  22. }
  23. bw.close();//关闭
  24. }
  25. }
3.2把文本文件中的数据以字符串形式按行输入到ArrayList中
  1. import java.io.BufferedReader;
  2. import java.io.File;
  3. import java.io.FileReader;
  4. import java.io.IOException;
  5. import java.util.ArrayList;
  6. public class CopyTxttoArrayDemo {
  7. /**
  8. * 分析:
  9. * A:利用BufferedReader按行读入数据
  10. * B:将数据转换为String
  11. * C:存入ArrayList
  12. * D:遍历,在控制台显示
  13. */
  14. public static void main(String[] args)throws IOException {
  15. // TODO Auto-generated method stub
  16. BufferedReader br=new BufferedReader(
  17. new FileReader(new File("a.txt")));
  18. ArrayList<String> myarray=new ArrayList<String>();
  19. String s=null;
  20. while((s=br.readLine())!=null){
  21. myarray.add(s);
  22. }
  23. for(String st:myarray){
  24. System.out.println(st);
  25. }
  26. }
  27. }
3.3复制单级文件夹
  1. import java.io.BufferedReader;
  2. import java.io.BufferedWriter;
  3. import java.io.File;
  4. import java.io.FileReader;
  5. import java.io.FileWriter;
  6. import java.io.IOException;
  7. public class CopyFoldertoFolder {
  8. /**
  9. * @param args
  10. * 分析:
  11. * 源文件夹:aaa
  12. * 目标文件夹:bbb
  13. * A:单级文件夹,获取该文件夹下所有文件
  14. * B:判断目标文件夹是否存在,否,创建
  15. * C:将所有文件写入目标文件夹中
  16. */
  17. public static void main(String[] args) throws IOException{
  18. // TODO Auto-generated method stub
  19. //封装源文件夹下的所有文件
  20. File myFile=new File("aaa");
  21. File[] myFileList=myFile.listFiles();
  22. //封装目标文件夹
  23. File aimFile=new File("bbb");
  24. if(!aimFile.exists()){
  25. aimFile.mkdir();
  26. }
  27. //复制文件进另外一个文件
  28. for(File fl:myFileList){
  29. copyFile(fl,aimFile);
  30. }
  31. }
  32. private static void copyFile(File fl, File aimFile) throws IOException{
  33. // 源文件的表示,直接用fl来构建就好
  34. BufferedReader br=new BufferedReader(new FileReader(fl));
  35. //目标文件,必须用File+String的方式构建目标文件夹下的目标文件。否则,就不是复制到目标文件夹下了。
  36. BufferedWriter bw=new BufferedWriter(
  37. new FileWriter(new File(aimFile,fl.getName())));
  38. String st=null;
  39. while((st=br.readLine())!=null){
  40. bw.write(st);
  41. bw.newLine();
  42. bw.flush();
  43. }
  44. bw.close();
  45. br.close();
  46. }
  47. }
3.4复制多级文件夹

以最开始的为例子:
1:"aaa"文件夹和"d:\"进入copyFolders
2:判断“aaa”是不是文件夹
3:是文件夹。
|----3.1:首先在d:\ 下创建aaa文件夹
|----3.2:遍历原来的aaa文件夹,得到其中每一个内容 fl。
|----3.3:把 fl 和 d:\aaa 传入copyFolders,开始递归。回到2
4:不是文件夹(假设aaa不是文件夹)
|----4.1:在d:\ 下创建aaa同名空文件。
|----4.2:将源文件“aaa”复制到d:\ 下的aaa空文件中

  1. package exercise;
  2. import java.io.BufferedInputStream;
  3. import java.io.BufferedOutputStream;
  4. import java.io.File;
  5. import java.io.FileInputStream;
  6. import java.io.FileOutputStream;
  7. import java.io.IOException;
  8. public class CopyFolderstoFolders {
  9. /**
  10. * 需求:将源文件夹下所有内容复制到目标文件夹下
  11. * 分析:
  12. * A:封装源文件夹,以及目标文件夹
  13. * B:判断源是否是文件夹
  14. * C1:是:封装文件夹下所有内容,遍历,回到B
  15. * C2:否:复制文件到另一文件夹中
  16. */
  17. public static void main(String[] args) throws IOException{
  18. // 封装源文件夹与目标文件夹
  19. File srcFolder=new File("aaa");
  20. File aimFolder=new File("d:\\");
  21. copyFolders(srcFolder,aimFolder);
  22. }
  23. private static void copyFolders(File srcFolder, File aimFolder) throws IOException{
  24. //注意,先判断,后封装!!!!
  25. //先判断源文件是否是文件夹
  26. if(srcFolder.isDirectory()){
  27. //是文件夹,在目标位置创造同名文件夹
  28. File destFile=new File(aimFolder,srcFolder.getName());
  29. destFile.mkdir();
  30. //封装其下所有内容
  31. File[] srcFileList=srcFolder.listFiles();
  32. for(File fl:srcFileList){
  33. //遍历,递归
  34. copyFolders(fl,destFile);
  35. }
  36. }else{
  37. //不是文件夹
  38. //先在目标文件夹下创建同名文件
  39. File destFile=new File(aimFolder,srcFolder.getName());
  40. //文件对文件的复制
  41. copy(srcFolder,destFile);
  42. }
  43. }
  44. //复制文件
  45. private static void copy(File srcFolder, File destFile)throws IOException {
  46. BufferedInputStream bis=new BufferedInputStream(
  47. new FileInputStream(srcFolder));
  48. BufferedOutputStream bos=new BufferedOutputStream(
  49. new FileOutputStream(destFile));
  50. int len=0;
  51. byte[] bys=new byte[1024];
  52. while((len=bis.read(bys))!=-1){
  53. bos.write(bys, 0, len);
  54. }
  55. bos.close();
  56. bis.close();
  57. }
  58. }
3.5复制单级文件夹下特定文件到新的文件夹,并改名
  1. package exercise;
  2. import java.io.BufferedInputStream;
  3. import java.io.BufferedOutputStream;
  4. import java.io.File;
  5. import java.io.FileInputStream;
  6. import java.io.FileOutputStream;
  7. import java.io.FilenameFilter;
  8. import java.io.IOException;
  9. public class CopyandRename {
  10. /**
  11. * @param args
  12. * 需求:
  13. * 将单级文件夹bbb中的.java文件复制到和bbb同目录下的ccc文件夹中
  14. * 并改名为a3.jad,b3.jad.
  15. *分析:
  16. * A:获取bbb中所有.java文件
  17. * B:将获取到的.java文件复制到ccc下
  18. * C:在ccc下对文件进行改名
  19. * PS:若是不复制之间改名到CCC下的话,相当于把bbb中文件剪
  20. * 切到CCC中在改名。
  21. */
  22. public static void main(String[] args)throws IOException {
  23. //封装源文件夹和目标文件夹
  24. File srcFolder=new File("bbb");
  25. File destFolder=new File("ccc");
  26. //判断目标文件夹是否存在
  27. if(!destFolder.exists()){
  28. destFolder.mkdir();
  29. }
  30. //获取所有以.java结尾的文件
  31. File[] srcFileList=srcFolder.listFiles(new FilenameFilter() {
  32. @Override
  33. public boolean accept(File dir, String name) {
  34. // 判断是否是文件,以及判断是否以.java结尾
  35. return new File(dir,name).isFile()
  36. && name.endsWith(".java");
  37. }
  38. });
  39. //复制到ccc中
  40. for(File fl:srcFileList){
  41. File destFile=new File(destFolder,fl.getName());
  42. copyFile(fl,destFile);
  43. }
  44. //获取ccc中所有文件
  45. File[] destFileList=destFolder.listFiles();
  46. //改名
  47. for(File fl:destFileList){
  48. String oldname=fl.getName();
  49. String newName=oldname.replaceAll(".java", ".jad");
  50. fl.renameTo(new File(destFolder,newName));
  51. }
  52. }
  53. //复制文件
  54. private static void copyFile(File fl, File destFile)throws IOException {
  55. BufferedInputStream bis=new BufferedInputStream(
  56. new FileInputStream(fl));
  57. BufferedOutputStream bos=new BufferedOutputStream(
  58. new FileOutputStream(destFile));
  59. int len=0;
  60. byte[] bys=new byte[1024];
  61. while((len=bis.read(bys))!=-1){
  62. bos.write(bys, 0, len);
  63. }
  64. bos.close();
  65. bis.close();
  66. }
  67. }
3.6输入N个学生姓名和成绩,按照成绩顺序输出到txt文件中
  1. package exercise;
  2. import java.io.BufferedWriter;
  3. import java.io.File;
  4. import java.io.FileWriter;
  5. import java.io.IOException;
  6. import java.util.Comparator;
  7. import java.util.Scanner;
  8. import java.util.TreeSet;
  9. //创建学生类
  10. class Student{
  11. private String name;
  12. private int chinese;
  13. private int math;
  14. private int english;
  15. public Student(String name, int chinese, int math, int english) {
  16. super();
  17. this.name = name;
  18. this.chinese = chinese;
  19. this.math = math;
  20. this.english = english;
  21. }
  22. public String getName() {
  23. return name;
  24. }
  25. public void setName(String name) {
  26. this.name = name;
  27. }
  28. public int getChinese() {
  29. return chinese;
  30. }
  31. public void setChinese(int chinese) {
  32. this.chinese = chinese;
  33. }
  34. public int getMath() {
  35. return math;
  36. }
  37. public void setMath(int math) {
  38. this.math = math;
  39. }
  40. public int getEnglish() {
  41. return english;
  42. }
  43. public void setEnglish(int english) {
  44. this.english = english;
  45. }
  46. public int getSum(){
  47. return chinese+math+english;
  48. }
  49. }
  50. public class InsertStuentScoreinOder {
  51. /**
  52. * 需求:输入5个学生成绩,按照其总分,语文,数学,外语,姓名的顺序排序
  53. * 分析:
  54. * A:构建学生类,能够获得其总分,语数外姓名等信息
  55. * B:利用TreeSet存储,自定义comparator
  56. * C:输出到txt文件中
  57. * @throws IOException
  58. */
  59. public static void main(String[] args) throws IOException {
  60. //用来存储学生信息,自定义比较器
  61. TreeSet<Student> st=new TreeSet<Student>(new Comparator<Student>() {
  62. @Override
  63. public int compare(Student o1, Student o2) {
  64. //o2在前表示从大到小
  65. int r1=o2.getSum()-o1.getSum();
  66. int r2= r1==0?o2.getChinese()-o1.getChinese():r1;
  67. int r3= r2==0?o2.getMath()-o1.getMath():r2;
  68. int r4= r3==0?o2.getEnglish()-o1.getEnglish():r3;
  69. int r5= r4==0?o2.getName().compareTo(o1.getName()):r4;
  70. return r5;
  71. }
  72. });
  73. //读入数据,注意Scanner要在内部定义,不然in.nextLine在循环
  74. //第二次会因为读入换行符而失效
  75. for(int i=1;i<=3;i++){
  76. Scanner in =new Scanner(System.in);
  77. System.out.println("name");
  78. String name=in.nextLine();
  79. System.out.println("chinese");
  80. int chinese=in.nextInt();
  81. System.out.println("math");
  82. int math=in.nextInt();
  83. System.out.println("english");
  84. int english=in.nextInt();
  85. Student s=new Student(name,chinese,math,english);
  86. st.add(s);
  87. }
  88. //封装目标文件
  89. File score=new File("Student.txt");
  90. //创建输出流
  91. BufferedWriter bw=new BufferedWriter(
  92. new FileWriter(score));
  93. for(Student stu:st){
  94. //构造字符串
  95. StringBuilder sbu=new StringBuilder();
  96. sbu.append(stu.getName()).append(" C:").append(stu.getChinese()).append(" M:").append(stu.getMath()).append(" E:").append(stu.getEnglish());
  97. String line=sbu.toString();
  98. //输出
  99. bw.write(line);
  100. bw.newLine();
  101. bw.flush();
  102. }
  103. //关闭
  104. bw.close();
  105. }
  106. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注