16 文件与流

什么是文件?

文件可认为是相关记录或放在一起的数据的集合

文件一般存储在哪里?

image.png

JAVA程序如何访问文件属性?

java.io.File 类

File类访问文件属性

image.png

JAVA中的文件及目录处理类

在Java中提供了操作文件及目录(即我们所说的文件夹)类File。有以下几点注意事项:

(1)不论是文件还是目录都使用File类操作;

(2)File类只提供操作文件及目录的方法,并不能访问文件的内容,所以他描述的是文件本身的属性;

(3)如果要访问文件本身,用到了我们下面要学习的IO流.

一:构造方法

File 文件名/目录名 = new File("文字路径字符串");

在Java中提供了几种创建文件及目录的构造方法,但大体上都是用参数中的文字路径字符串来创建。

二:一般方法

(1)文件检测相关方法

boolean isDirectory():判断File对象是不是目录

boolean isFile():判断File对象是不是文件

boolean exists():判断File对象对应的文件或目录是不是存在

(2)文件操作的相关方法

boolean createNewFile():路径名指定的文件不存在时,创建一个新的空文件

boolean delete():删除File对象对应的文件或目录

(3)目录操作的相关方法

boolean mkdir():单层创建空文件夹

boolean mkdirs():多层创建文件夹

File[] listFiles():返回File对象表示的路径下的所有文件对象数组

(4)访问文件相关方法

String getName():获得文件或目录的名字

String getAbsolutePath():获得文件目录的绝对路径

String getParent():获得对象对应的目录的父级目录

long lastModified():获得文件或目录的最后修改时间

long length() :获得文件内容的长度

目录的创建

public class MyFile {
  public static void main(String[] args) {
      //创建一个目录
      File file1 = new File("d:\\test");
      //判断对象是不是目录
      System.out.println("是目录吗?"+file1.isDirectory());
      //判断对象是不是文件
      System.out.println("是文件吗?"+file1.isFile());
      //获得目录名
      System.out.println("名称:"+file1.getName());
      //获得相对路径
      System.out.println("相对路径:"+file1.getPath());
      //获得绝对路径
      System.out.println("绝对路径:"+file1.getAbsolutePath());
      //最后修改时间
      System.out.println("修改时间:"+file1.lastModified());
      //文件大小
      System.out.println("文件大小:"+file1.length());
  }
}

程序首次运行结果:

是目录吗?false
是文件吗?false
名称:test
相对路径:d:\test
绝对路径:d:\test
修改时间:0
文件大小:0

file1对象是目录啊,怎么在判断“是不是目录”时输出了false呢?这是因为只是创建了代表他是目录的对象,还没有真正的创建,这时候要用到mkdirs()方法,如下:

public class MyFile {
    public static void main(String[] args) {
        //创建一个目录
        File file1 = new File("d:\\test\\test");
        file1.mkdirs();//创建了多级目录
        //判断对象是不是目录
        System.out.println("是目录吗?"+file1.isDirectory());     
    }
}

文件的创建

public class MyFile {
    public static void main(String[] args) {
        //创建一个文件
        File file1 = new File("d:\\a.txt");
                                                                                                                                                                                                                                                                
        //判断对象是不是文件
        System.out.println("是文件吗?"+file1.isFile());  
    }
}

首次运行结果:

是文件吗?false

同样会发现类似于上面的问题,这是因为只是代表了一个文件对象,并没有真正的创建,要用到createNewFile()方法,如下

public class MyFile {
    public static void main(String[] args) {
        //创建一个文件对象
        File file1 = new File("d:\\a.txt");
        try {
            file1.createNewFile();//创建真正的文件
        } catch (IOException e) {
            e.printStackTrace();
        }
        //判断对象是不是文件
        System.out.println("是文件吗?"+file1.isFile());  
    }
}

文件夹与文件的创建目录

文件时存放在文件夹下的,所以应该先创建文件夹,后创建文件,如下:

public class MyFile {
    public static void main(String[] args) {
        //代表一个文件夹对象,单层的创建
        File f3 = new File("d:/test");
        File f4 = new File("d:/test/a.txt");
        f3.mkdir();//先创建文件夹,才能在文件夹下创建文件
        try {
            f4.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
                                                                                                                                                                   
        //代表一个文件夹对象,多层的创建
        File f5= new File("d:/test/test/test");
        File f6 = new File("d:/test/test/test/a.txt");
        f5.mkdirs();//多层创建
        try {
            f6.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

运行结果为,在D磁盘的test文件夹下有一个a.txt,在D磁盘的test/test/test下有一个a.txt文件。

编程:判断是不是有这个文件,若有则删除,没有则创建

public class TestFileCreatAndDele {
    public static void main(String[] args) {
        File f1 = new File("d:/a.txt");
        if(f1.exists()){//文件在吗
            f1.delete();//在就删除
        }else{//不在
            try {
                f1.createNewFile();//就重新创建
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

文件的逐层读取

File的listFiles()只能列出当前文件夹下的文件及目录,那么其子目录下的文件及目录该如何获取呢?解决的办法有很多,在这运用递归解决.

//逐层获取文件及目录
public class TestFindFile {
    public static void openAll(File f) {// 递归的实现
        File[] arr = f.listFiles();// 先列出当前文件夹下的文件及目录
        for (File ff : arr) {
            if (ff.isDirectory()) {// 列出的东西是目录吗
                System.out.println(ff.getName());
                openAll(ff);// 是就继续获得子文件夹,执行操作
            } else {
                // 不是就把文件名输出
                System.out.println(ff.getName());
            }
        }
    }
    public static void main(String[] args) {
        File file = new File("d:/test");// 创建目录对象
        openAll(file);// 打开目录下的所有文件及文件夹
    }
}

如何读写文件?
通过流来读写文件
流是指一连串流动的字符,是以先进先出方式发送信息的通道

image.png

输入/输出流与数据源

image.png

Java流的分类

image.png

文本文件的读写

  • 用FileInputStream和FileOutputStream读写文本文件
  • 用BufferedReader和BufferedWriter读写文本文件

二进制文件的读写

  • 使用DataInputStream和DataOutputStream读写二进制文件

使用FileInputStream 读文本文件

image.png

InputStream类常用方法
int read( )
int read(byte[] b)
int read(byte[] b,int off,int len)
void close( )
子类FileInputStream常用的构造方法
FileInputStream(File file)
FileInputStream(String name)

一个一个字节的读

 public static void main(String[] args) throws IOException {
    // write your code here
        File file = new File("d:/我的青春谁做主.txt");
        FileInputStream fileInputStream = new FileInputStream(file);

        byte[] buffer = new byte[100];//保存从磁盘读到的字节
        int index = 0;

        int content = fileInputStream.read();//读文件中的一个字节

        while (content != -1)//文件中还有内容,没有读完
        {
            buffer[index] = (byte)content;
            index++;

            //读文件中的下一个字节
            content = fileInputStream.read();
        }

        //此时buffer数组中读到了文件的所有字节

        String string = new String(buffer,0, index);

        System.out.println(string);

    }


一批一批的读

  public static void main(String[] args) throws IOException {
        // write your code here

        File file = new File("d:/我的青春谁做主.txt");
        FileInputStream fileInputStream = new FileInputStream(file);

        byte[] buffer = new byte[SIZE];//保存从磁盘读到的字节


        int len = fileInputStream.read(buffer);//第一次读文件中的100个字节
        while (len != -1)
        {
            String string = new String(buffer,0, len);
            System.out.println(string);
            //读下一批字节
            len = fileInputStream.read(buffer);
        }
    }

使用FileOutputStream 写文本文件

image.png
public class FileOutputStreamTest {
    
    public static void main(String[] args) {
        FileOutputStream fos=null;
         try {
             String str ="好好学习Java";
             byte[] words  = str.getBytes();
             fos = new FileOutputStream("D:\\myDoc\\hello.txt");
             fos.write(words, 0, words.length);
             System.out.println("hello文件已更新!");
          }catch (IOException obj) {
              System.out.println("创建文件时出错!");
          }finally{
              try{
                  if(fos!=null)
                      fos.close();
              }catch (IOException e) {
                 e.printStackTrace();
              }
          }
    }
}

OutputStream类常用方法
void write(int c)
void write(byte[] buf)
void write(byte[] b,int off,int len)
void close( )
子类FileOutputStream常用的构造方法
FileOutputStream (File file)
FileOutputStream(String name)
FileOutputStream(String name,boolean append)
1、前两种构造方法在向文件写数据时将覆盖文件中原有的内容
2、创建FileOutputStream实例时,如果相应的文件并不存在,则会自动创建一个空的文件

复制文件内容

文件“我的青春谁做主.txt”位于D盘根目录下,要求将此文件的内容复制到
C:\myFile\my Prime.txt中
实现思路

  1. 创建文件“D:\我的青春谁做主.txt”并自行输入内容
  2. 创建C:\myFile的目录。
  3. 创建输入流FileInputStream对象,负责对D:\我的青春谁做主.txt文件的读取。
  4. 创建输出流FileOutputStream对象,负责将文件内容写入到C:\myFile\my Prime.txt中。
  5. 创建中转站数组words,存放每次读取的内容。
  6. 通过循环实现文件读写。
  7. 关闭输入流、输出流
  public static void main(String[] args) throws IOException {
        //创建E:\myFile的目录。

        File folder = new File("E:\\myFile");
        if (!folder.exists())//判断目录是否存在
        {
            folder.mkdirs();//如果不存在,创建该目录
        }

        //创建输入流
        File fileInput = new File("d:/b.rar");
        FileInputStream fileInputStream = new FileInputStream(fileInput);
        //创建输出流
        FileOutputStream fileOutputStream = new FileOutputStream("E:\\myFile\\c.rar");
        //创建中转站数组buffer,存放每次读取的内容
        byte[] buffer = new byte[1000];

        //从fileInputStream(d:/我的青春谁做主.txt)中读100个字节到buffer中
        int length = fileInputStream.read(buffer);

        int count = 0;
        while (length != -1) //这次读到了至少一个字节
        {
            System.out.println(length);
            //将buffer中内容写入到输出流(E:\myFile\myPrime.txt)
            fileOutputStream.write(buffer,0,length);

            //继续从输入流中读取下一批字节
            length = fileInputStream.read(buffer);
            count++;
        }
        System.out.println(count);

        fileInputStream.close();
        fileOutputStream.close();

    }

使用字符流读写文件

使用FileReader读取文件

   public static void main(String[] args) throws IOException {
        //
        FileReader fileReader = new FileReader("D:/我的青春谁做主.txt");

        char[] array = new char[100];
        int length = fileReader.read(array);
        StringBuilder sb = new StringBuilder();
        while (length != -1)
        {
            sb.append(array);
            length = fileReader.read(array);
        }

        System.out.println(sb.toString());
        fileReader.close();

    }

BufferedReader类

如何提高字符流读取文本文件的效率?
使用FileReader类与BufferedReader类
BufferedReader类是Reader类的子类
BufferedReader类带有缓冲区
按行读取内容的readLine()方法


image.png
  public static void main(String[] args) throws IOException {
        FileReader fileReader = new FileReader("D:/我的青春谁做主.txt");

        BufferedReader bufferedReader = new BufferedReader(fileReader);

        String strContent = bufferedReader.readLine();
        StringBuilder sb = new StringBuilder();
        while (strContent != null)
        {
            sb.append(strContent);
            sb.append("\n");
            sb.append("\r");
            strContent = bufferedReader.readLine();
        }

        System.out.println(sb.toString());
        fileReader.close();
        bufferedReader.close();
    }

使用FileWriter写文件

public class WriterFiletTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        Writer fw=null;
        try {
              //创建一个FileWriter对象
              fw=new FileWriter("D:\\myDoc\\简介.txt"); 
              //写入信息
              fw.write("我热爱我的团队!");            
              fw.flush();  //刷新缓冲区
             
        }catch(IOException e){
              System.out.println("文件不存在!");
        }finally{
            try {
                if(fw!=null)
                    fw.close();  //关闭流
             } catch (IOException e) {
                e.printStackTrace();
             }
        }
    }

}

如何提高字符流写文本文件的效率?
使用FileWriter类与BufferedWriter类
BufferedWriter类是Writer类的子类
BufferedWriter类带有缓冲区

image.png
public class BufferedWriterTest {
    public static void main(String[] args) {
        FileWriter fw=null;
        BufferedWriter bw=null;
        FileReader fr=null;
        BufferedReader br=null;
        try {
           //创建一个FileWriter 对象
           fw=new FileWriter("D:\\myDoc\\hello.txt"); 
           //创建一个BufferedWriter 对象
           bw=new BufferedWriter(fw); 
           bw.write("大家好!"); 
           bw.write("我正在学习BufferedWriter。"); 
           bw.newLine(); 
           bw.write("请多多指教!"); 
           bw.newLine();               
           bw.flush();
                       
           //读取文件内容
            fr=new FileReader("D:\\myDoc\\hello.txt"); 
            br=new BufferedReader(fr); 
            String line=br.readLine();
            while(line!=null){ 
                System.out.println(line);
                line=br.readLine(); 
            }
          
            fr.close(); 
           }catch(IOException e){
                System.out.println("文件不存在!");
           }finally{
               try{
                   if(fw!=null)
                       fw.close();
                   if(br!=null)
                       br.close();
                   if(fr!=null)
                       fr.close();  
               }catch(IOException ex){
                    ex.printStackTrace();
               }
           }
    }
}

练习

格式模版保存在文本文件pet.template中,内容如下:
您好!
我的名字是{name},我是一只{type}。
我的主人是{master}。
其中{name}、{type}、{master}是需要替换的内容,现在要求按照模板格式保存宠物数据到文本文件,即把{name}、{type}、{master}替换为具体的宠物信息,该如何实现呢?

实现思路
1.创建字符输入流BufferedReader对象
2.创建字符输出流BufferedWriter对象

  1. 建StringBuffer对象sbf,用来临时存储读取的
    数据
  2. 通过循环实现文件读取,并追加到sbf中
  3. 使用replace()方法替换sbf中的内容
  4. 将替换后的内容写入到文件中
  5. 关闭输入流、输出流
public class ReaderAndWriterFile {

     public void replaceFile(String file1,String file2) {   
           BufferedReader reader = null;
           BufferedWriter writer = null;
         try {
            //创建 FileReader对象和FileWriter对象.
            FileReader fr  = new FileReader(file1);  
            FileWriter fw = new FileWriter(file2);
            //创建 输入、输入出流对象.
            reader = new BufferedReader(fr);
            writer = new BufferedWriter(fw);
            String line = null;
            StringBuffer sbf=new StringBuffer();  
            //循环读取并追加字符
            while ((line = reader.readLine()) != null) {
                sbf.append(line);  
            }
            System.out.println("替换前:"+sbf);
            /*替换内容*/
            String newString=sbf.toString().replace("{name}", "欧欧");
            newString = newString.replace("{type}", "狗狗");
            newString = newString.replace("{master}", "李伟");
            System.out.println("替换后:"+newString);
            writer.write(newString);  //写入文件       
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            //关闭 reader 和 writer.
            try {
                if(reader!=null)
                    reader.close();
                if(writer!=null)
                    writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
        ReaderAndWriterFile obj = new ReaderAndWriterFile();
        obj.replaceFile("c:\\pet.template", "D:\\myDoc\\pet.txt");          
    }
}

使用字符流读写文本更合适
使用字节流读写字节文件(音频,视频,图片,压缩文件等)更合适,文本文件也可以看成是有字节组成

图片拷贝

public class move {  
    public static void main(String[] args)  
    {  
        String src="E:/DesktopFile/Android/CSDN.jpg";  
        String target="E:/DesktopFile/Android/test/CSDN.jpg";  
        copyFile(src,target);  
    }  
    public static void copyFile(String src,String target)  
        {     
            File srcFile = new File(src);    
               File targetFile = new File(target);    
               try {    
                   InputStream in = new FileInputStream(srcFile);     
                   OutputStream out = new FileOutputStream(targetFile);    
                   byte[] bytes = new byte[1024];    
                   int len = -1;    
                   while((len=in.read(bytes))!=-1)  
                   {    
                       out.write(bytes, 0, len);    
                   }    
                   in.close();    
                   out.close();    
               } catch (FileNotFoundException e) {    
                   e.printStackTrace();    
               } catch (IOException e) {    
                   e.printStackTrace();    
               }    
               System.out.println("文件复制成功");   
  
  
        }  
                 
    }  

在计算机中文件是byte 、byte、byte地存储
FileReader在读取文件的时候,就是一个一个byte地读取,
BufferedReader则是自带缓冲区,默认缓冲区大小为8X1024

通俗地讲就是:
FileReader在读取文件的时候,一滴一滴地把水从一个缸复制到另外一个缸
BufferedReader则是一桶一桶地把水从一个缸复制到另外一个缸。

练习 统计某个文件夹下所有java文件代码行数之和

public class CodeLinesCount {

    public static int countJavaFileLines(String strFileName) throws IOException {
        FileReader fileReader = new FileReader("e:/mycode/" + strFileName);
        BufferedReader bufferedReader = new BufferedReader(fileReader);

        int count = 0;
        String strLine = bufferedReader.readLine();
        while (strLine != null)
        {
            count++;
            strLine = bufferedReader.readLine();
        }

        return count;
    }


    public static void main(String[] args) throws IOException {

        File file = new File("e:/mycode/");
        File[] files = file.listFiles();
        int totalCount = 0;
        for(File file1 : files)
        {
            System.out.println(file1.getName());
            int count = countJavaFileLines(file1.getName());
            totalCount += count;
        }

//        int count = countJavaFileLines("MyGuessWord.java");
        System.out.println(totalCount);
    }
}

练习

写个程序读取以下学生信息文件,计算出每个学生总分,平均分,名次,写入到一个新文件中

学号 姓名   语文 数学 英语 平均值 总值  排序 
1   李守东   83  73  75 
2   徐贤坤   58  58  87 
3   钱云宋   41  86  90 
4   陈平     83  43  65 
5   金荣权   93  88  63 
6   陈如棉   99  93  43 
7   章可可   98  62  72 
8   陈伟奔   87  43  76 
9   张如祥   69  58  78 
10  丁尚游   80  56  57 
11  林宏旦   91  90  76 
12  曾上腾   100 96  54 
13  谢作品   82  100 55 
14  温从卫   73  46  101 
15  李明察   81  41  75 
16  彭鸿威   46  46  89 
17  翁文秀   57  43  58 
18  陈家伟   63  58  98 
19  温正考   100 64  57 
20  周文湘   50  50  79 
21  吴杰     65  65  83 
22  赖登城   60  79  53 
23  聂树露   51  76  45 
24  张雅琴   68  95  56 
25  曾瑞约   88  63  58 
26  王志强   96  79  78 
27  徐贤所   66  46  74 
28  陈祥枭   82  96  91 
29  温婷婷   41  73  96 
30  应孔余   66  81  71 
31  宋成取   71  68  62 
32  黄益省   65  56  43 
33  陈思文   55  100 44 
34  上官福新 64  62  70 
35  钟国横   49  69  56 
36  林型涨   78  73  50 

需要生成的文件

学号  姓名  语文  数学  英语  平均值 总值  排序
1   李守东 83  73  75  77  231 9   
2   徐贤坤 58  58  87  67  203 21  
3   钱云宋 41  86  90  72  217 15  
4   陈平  83  43  65  63  191 29  
5   金荣权 93  88  63  81  244 5   
6   陈如棉 99  93  43  78  235 7   
7   章可可 98  62  72  77  232 8   
8   陈伟奔 87  43  76  68  206 19  
9   张如祥 69  58  78  68  205 20  
10  丁尚游 80  56  57  64  193 27  
11  林宏旦 91  90  76  85  257 2   
12  曾上腾 100 96  54  83  250 4   
13  谢作品 82  100 55  79  237 6   
14  温从卫 73  46  101 73  220 11  
15  李明察 81  41  75  65  197 25  
16  彭鸿威 46  46  89  60  181 31  
17  翁文秀 57  43  58  52  158 36  
18  陈家伟 63  58  98  73  219 12  
19  温正考 100 64  57  73  221 10  
20  周文湘 50  50  79  59  179 32  
21  吴杰  65  65  83  71  213 16  
22  赖登城 60  79  53  64  192 28  
23  聂树露 51  76  45  57  172 34  
24  张雅琴 68  95  56  73  219 13  
25  曾瑞约 88  63  58  69  209 18  
26  王志强 96  79  78  84  253 3   
27  徐贤所 66  46  74  62  186 30  
28  陈祥枭 82  96  91  89  269 1   
29  温婷婷 41  73  96  70  210 17  
30  应孔余 66  81  71  72  218 14  
31  宋成取 71  68  62  67  201 22  
32  黄益省 65  56  43  54  164 35  
33  陈思文 55  100 44  66  199 24  
34  上官新 64  62  70  65  196 26  
35  钟国横 49  69  56  58  174 33  
36  林型涨 78  73  50  67  201 23  

代码:
学生类:

package com.company;

public class Student implements Comparable {
    private int sno;
    private String name;
    private int chinese_score;
    private int math_score;
    private int eng_score;
    private int avg_score;
    private int total_score;

    public int getEng_score() {
        return eng_score;
    }

    public void setEng_score(int eng_score) {
        this.eng_score = eng_score;
    }

    public int getSno() {
        return sno;
    }

    public void setSno(int sno) {
        this.sno = sno;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getChinese_score() {
        return chinese_score;
    }

    public void setChinese_score(int chinese_score) {
        this.chinese_score = chinese_score;
    }

    public int getMath_score() {
        return math_score;
    }

    public void setMath_score(int math_score) {
        this.math_score = math_score;
    }

    public int getAvg_score() {
        return avg_score;
    }

    public void setAvg_score(int avg_score) {
        this.avg_score = avg_score;
    }

    public int getTotal_score() {
        return total_score;
    }
    public void setTotal_score(int total_score) {
        this.total_score = total_score;
    }

    @Override
    public String toString() {
        return "Student{" +
                "sno=" + sno +
                ", name='" + name + '\'' +
                ", chinese_score=" + chinese_score +
                ", math_score=" + math_score +
                ", eng_score=" + eng_score +
                ", avg_score=" + avg_score +
                ", total_score=" + total_score +
                '}';
    }

    @Override
    public int compareTo(Object o) {
        Student student = (Student)o;
//        if(student.getSno() < this.getSno())
//        {
//            return 5;
//        }
//        else if(student.getSno() > this.getSno())
//        {
//            return -9;
//        }
//        else
//        {
//            return 0;
//        }

//        return this.getName().compareTo(student.getName());//打算按学生姓名排序
//        return this.getSno() - student.getSno();//打算按学生学号排序
          return student.getTotal_score() - this.getTotal_score();//打算按学生总分排序
    }
}

主类:

package com.company;

import java.io.*;
import java.util.*;

/**
 * Created by ttc on 2018/1/15.
 */
//        学号 姓名   语文 数学 英语 平均值 总值  排序
//        1   李守东   83  73  75
//        2   徐贤坤   58  58  87
//        3   钱云宋   41  86  90
//        4   陈平     83  43  65
//        5   金荣权   93  88  63

public class ComputeStudent {
    public static void main(String[] args) throws IOException {
        FileReader fileReader = new FileReader("e:/student_score.txt");
        BufferedReader bufferedReader = new BufferedReader(fileReader);

        String strStudentInfo = bufferedReader.readLine();//跳过头部
        List<Student> studentList = new ArrayList<>();
        strStudentInfo = bufferedReader.readLine();
        while(strStudentInfo != null)
        {

            String[] strings = strStudentInfo.split(" ");

            List<String> stringList = new ArrayList<String>();//保存的是一个学生的学号,姓名,三科成绩

            for(String str : strings)
            {
                if(!str.equals(""))
                {
                    stringList.add(str);
                }
            }

            //创建学生对象
            Student student = new Student();

            int sno = Integer.parseInt(stringList.get(0));
            student.setSno(sno);

            student.setName(stringList.get(1));
            int china_score = Integer.parseInt(stringList.get(2));
            student.setChinese_score(china_score);
            int math_score = Integer.parseInt(stringList.get(3));
            student.setMath_score(math_score);
            int eng_score = Integer.parseInt(stringList.get(4));
            student.setEng_score(eng_score);
            student.setTotal_score(china_score+math_score+eng_score);
            student.setAvg_score((china_score+math_score+eng_score)/3);

            studentList.add(student);

            strStudentInfo = bufferedReader.readLine();
        }

        System.out.println(strStudentInfo);

        FileWriter fileWriter = new FileWriter("e:/student_score_new.txt");
        BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);


        bufferedWriter.write("学号\t姓名\t语文\t数学\t英语\t平均值\t总值\t排序");
        bufferedWriter.newLine();


        List<Student> studentListOld = new ArrayList<>();
        studentListOld.addAll(studentList);//studentListOld里学生是按照学号排序

        Collections.sort(studentList);//studentList里学生是按照成绩排序

        //保存每个学生的名字和排名的键值对
        Map<String,Integer> mapName2Rank = new HashMap<>();

        int index = 1;
        for(Student student : studentList)
        {
            mapName2Rank.put(student.getName(), index++);
        }

        //遍历list,将list里的每一个student对象写入到文件中
        for(Student student : studentListOld)
        {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(student.getSno());
            stringBuilder.append("\t");
            stringBuilder.append(student.getName());
            stringBuilder.append("\t");
            stringBuilder.append(student.getChinese_score());
            stringBuilder.append("\t");
            stringBuilder.append(student.getMath_score());
            stringBuilder.append("\t");
            stringBuilder.append(student.getEng_score());
            stringBuilder.append("\t");
            stringBuilder.append(student.getAvg_score());
            stringBuilder.append("\t");
            stringBuilder.append(student.getTotal_score());
            stringBuilder.append("\t");

            String strStudentName = student.getName();
            int rank = mapName2Rank.get(strStudentName);//拿到了该名学生的名次

            stringBuilder.append(rank);
            stringBuilder.append("\t");

            bufferedWriter.write(stringBuilder.toString());
            bufferedWriter.newLine();
        }

        bufferedWriter.flush();

        fileReader.close();
        fileWriter.close();
        bufferedReader.close();
        bufferedWriter.close();
    }
}


DataOutputStream和DataInputStream

DataOutputStream数据输出流: 将java基本数据类型写入数据输出流中。
DataInputStream数据输入流:将DataOutputStream写入流中的数据读入。

DataOutputStream中write的方法重载:

继承了字节流父类的两个方法:
(1)void write(byte[] b,int off,int len);
(2)void write(int b);//写入UTF数值,代表字符
注意字节流基类不能直接写入string 需要先将String转化为getByte()转化为byte数组写入
特有的指定基本数据类型写入:
(1)void writeBoolean(boolean b);//将一个boolean值以1byte形式写入基本输出流。
(2)void writeByte(int v);//将一个byte值以1byte值形式写入到基本输出流中。
(3)void writeBytes(String s);//将字符串按字节顺序写入到基本输出流中。
(4)void writeChar(int v);//将一个char值以2byte形式写入到基本输出流中。先写入高字节。写入的也是编码值;
(5)void writeInt(int v);//将一个int值以4byte值形式写入到输出流中先写高字节。
(6)void writeUTF(String str);//以机器无关的的方式用UTF-8修改版将一个字符串写到基本输出流。该方法先用writeShort写入两个字节表示后面的字节数。

DataInputStream中read方法重载:

继承了字节流父类的方法:
int read();
int read(byte[] b);
int read(byte[] buf,int off,int len);
对应write方法的基本数据类型的读出:
String readUTF();//读入一个已使用UTF-8修改版格式编码的字符串
boolean readBoolean;
int readInt();
byte readByte();
char readChar();
注意:
基本数据类型的写入流和输出流,必须保证以什么顺序按什么方式写入数据,就要按什么顺序什么方法读出数据,否则会导致乱码,或者异常产生。

public class Test {

public static void main(String[] args) {
    DataOutputStream dos = null;
    DataInputStream dis = null;
    try {
        //写入基本数据类型
        dos = new DataOutputStream(new FileOutputStream("d://dataTest.txt"));
        dos.writeUTF("你好呀,ok");
        dos.writeInt(18888);
        dos.writeLong(188888);
        dos.writeByte(123);
        dos.writeFloat(1.344f);
        dos.writeBoolean(true);
        dos.writeDouble(1.444444d);
        dos.writeChar(49);
        
        dos.flush();
        dos.close();
        //读出基本数据类型
        dis = new DataInputStream(new FileInputStream("d://dataTest.txt"));

        System.out.println(dis.readUTF());          
        System.out.println(dis.readInt());
        System.out.println(dis.readLong());
        System.out.println(dis.readByte());
        System.out.println(dis.readFloat());
        System.out.println(dis.readBoolean());
        System.out.println(dis.readDouble());
        System.out.println(dis.readChar());
        
        dis.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
  }
}

package com.company;

import java.io.*;

/**
 * Created by ttc on 2018/6/7.
 */
public class DataStream {
    public static void main(String[] args) throws IOException {
        String[] strings = {"main","flush","String","FileOutputStream","java.io.*"};
        FileOutputStream fileOutputStream = new FileOutputStream("e:/output.txt");
        DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream);

        for(String string : strings)
        {
            int strlen = string.length();
            dataOutputStream.writeShort(strlen);
            dataOutputStream.writeBytes(string);
        }


        dataOutputStream.flush();
        dataOutputStream.close();

        FileInputStream fileInputStream = new FileInputStream("e:/output.txt");
        DataInputStream dataInputStream = new DataInputStream(fileInputStream);

        while(true)
        {
            try {
                short len = dataInputStream.readShort();
                byte[] bytes = new byte[len];
                dataInputStream.read(bytes);
                String string = new String(bytes,0,bytes.length);
                System.out.println(string);
            }
            catch (EOFException ex)
            {
                break;
            }

        }

    }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容

  • 一、流的概念和作用。 流是一种有顺序的,有起点和终点的字节集合,是对数据传输的总成或抽象。即数据在两设备之间的传输...
    布鲁斯不吐丝阅读 10,016评论 2 95
  • IO简单概述 IO解决问题 : 解决设备与设备之间的数据传输问题(硬盘 -> 内存 内存 -> 硬盘) 读和写文...
    奋斗的老王阅读 3,429评论 0 53
  • 最近在做一个 WEB 项目,需要调用 OCX 进行连接读卡器读卡。本来并不想用 OCX 技术,因为 ActiveX...
    安易学车阅读 2,186评论 1 5
  • 喜欢阳光,有阳光的地方,我的梦想就不会孤单,就算孤身一人走完了所有的路,也会贪恋明媚的阳光,因为会回归最初的...
    空空君阅读 291评论 0 3