0. 字节流与二进制文件

我的代码

public class dostest {

    public static void main(String[] args) {
        Student stus[] = new Student[3];
        stus[0] = new Student(1,"张三",19,65);
        stus[1] = new Student(2,"李四",19,75);
        stus[2] = new Student(3,"王五",20,85);
        try (DataOutputStream dos = new DataOutputStream(new FileOutputStream("d:\\student.data"))){
            for (int i = 0; i < stus.length; i++) {
                dos.writeInt(stus[i].getId());
                dos.writeUTF(stus[i].getName());
                dos.writeInt(stus[i].getAge());
                dos.writeDouble(stus[i].getGrade());
            }
        } catch ( IOException e) {
            e.printStackTrace();

        }
        try (DataInputStream dis = new DataInputStream(new FileInputStream("d:\\student.data"))){
            int id = dis.readInt();
            String name = dis.readUTF();
            int age = dis.readInt();
            double grade = dis.readDouble();
            Student stutest = new Student(id, name, age , grade);
            System.out.println(stutest.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

我的总结

1.二进制文件与文本文件的区别:
    <1>文本文件每条数据通常是固定长度的。以ASCII为例,每条数据(每个字符)都是1个字节。进制文件每条数据不固定。如short占两个字节,int占四个字节,float占8个字节
    <2>二进制文件是把内存中的数据按其在内存中的存储形式原样输出到磁盘上存放,也就是说存放的是数据的原形式;文本文件是把数据的终端形式的二进制数据输出到磁盘上存放,也就是说存放的是数据的终端形式。
2.遇到的问题:
    <1>在读写文件时,没有设置路径,导致没有写入;
    <2>在读文件后,创建了一个测试对象,在输出时报错,检查发现在try中创建对象,而在外面输出,导致报错。

1. 字符流与文本文件:使用 PrintWriter(写),BufferedReader(读)

我的代码

1.使用BufferedReader从编码为UTF-8的文本文件中读出学生信息,并组装成对象然后输出。

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;

public class BrTest {

    public static void main(String[] args) {
        Student stus[] = new Student[3];
        int count = 0 ;
        try(BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("d:/Students.txt"), "UTF-8"))) {
            String line  = null;
            while((line=br.readLine())!=null) {
                String[] tokens = line.split("\\ ");
                int id = Integer.parseInt(tokens[0]);
                String name = tokens[1];
                int age = Integer.parseInt(tokens[2]);
                double grade = Double.parseDouble(tokens[3]);
                stus[count++] = new Student(id, name, age , grade);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        for (int i = 0; i < stus.length; i++) {
            System.out.println(stus[i].toString());
        }

    }

}

2.从fileName指定的文本文件中读取所有学生,并将其放入到一个List中


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

public class ListreadStudents {
    public static  List readStudents(String fileName) {
        List<Student>  stuList = new ArrayList<>();
        try(BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(fileName), "UTF-8"))) {
            String line  = null;
            while((line=br.readLine())!=null) {
                String[] tokens = line.split("\\ ");
                int id = Integer.parseInt(tokens[0]);
                String name = tokens[1];
                int age = Integer.parseInt(tokens[2]);
                double grade = Double.parseDouble(tokens[3]);
                Student newstu = new Student(id, name, age , grade);
                stuList.add(newstu);

            }

        } catch (Exception e) {
            e.printStackTrace();
        }return stuList;

    }
    public static void main(String[] args) {
        String fileName = "d:/Students.txt";
        List<Student>  stuList = readStudents(fileName);
        System.out.println(stuList.toString());;

    }

}

3.使用PrintWriter将Student对象写入文本文件

import java.io.PrintWriter;

public class PwTest {
    public static void main(String[] args) {
        Student stus[] = new Student[3];
        stus[0] = new Student(1,"x",18,99.5);
        stus[1] = new Student(2,"y",19,100.0);
        stus[2] = new Student(3,"z",20,59.5);
        try (PrintWriter pw = new PrintWriter("d:/Pwtest.txt")){
            for (int i = 0; i < stus.length; i++) {
                pw.print(stus[i].getId()+" ");
                pw.print(stus[i].getName()+" ");
                pw.print(stus[i].getAge()+" ");
                pw.print(stus[i].getGrade()+" ");
                pw.write("\r\n");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

4.使用ObjectInputStream/ObjectOutputStream读写学生对象。

import java.io.*;
import java.util.*;
class ObjectStreamTest
{
   public static void main(String[] args)
   {
       try(ObjectOutputStream os=new ObjectOutputStream(new FileOutputStream("d:\\新建文本文档.txt"))){
           Student s1 = new Student(3,"王五",20,85);
           os.writeObject(s1);
       }
       catch (Exception e) {
           e.printStackTrace();
       }
       try(ObjectInputStream ois=new ObjectInputStream(new FileInputStream("d:\\新建文本文档.txt")))
            {
                Student StudentReader =(Student)ois.readObject();
                System.out.println(StudentReader);
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }

   }
}

总结

1.文件被printwriter重写时,会破坏之前的数据,而且编码也会变,再次运行会乱码,要使用notepad重新修改编码。
2.读取文件放入list的时候,我用的是bufferreader读出一行再进行分割,直接使用scanner进行格式化应该会更好一点。

2.缓冲流

我的代码

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

public class Comparetest {

    public static void main(String[] args) {
        String fileName="d:/comparetest.txt";
        try (PrintWriter pw = new PrintWriter(fileName);)
        {
            Random random=new Random();
            random.setSeed(100);
            double sum=0,average;
            for (int i = 0; i < 1000_0000; i++) {
                int num=random.nextInt(10);
                pw.println(num);
                sum+=num;

            }
            average=sum/1000_0000;
            System.out.format("%.5f", average);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

}
import static org.junit.jupiter.api.Assertions.*;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Scanner;

import org.junit.jupiter.api.Test;

class SpCompare {
    String fileName="d:/comparetest.txt";
    @Test
    void BufferedReadertest() throws FileNotFoundException, IOException {
        try (   BufferedReader br=new BufferedReader(new FileReader(fileName)))
        {
             String line=null;
                while((line=br.readLine())!=null)
                {

                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
    }
    @Test
    void Scannertest() throws FileNotFoundException, IOException{
         try (Scanner sc=new Scanner(new FileInputStream(fileName)))
            {
                while(sc.hasNextInt())
                {
                    sc.nextInt();
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
    }
}

测试结果

我的总结

1.Junit用于测试代码的性能,在要测试的代码前必须加@test标记;
2.通过创建一个很大的文件进行比较,我们发现缓冲流的效率要比scanner高的多。

3. 字节流之对象流

我的代码

   public static void writeStudent(List<Student> stuList)
{
       try(ObjectOutputStream os=new ObjectOutputStream(new FileOutputStream("d:\\新建文本文档.txt")))
       {
           os.writeObject(stuList);

       }
       catch (FileNotFoundException e) {
           e.printStackTrace();
       } catch (IOException e1) {
           e1.printStackTrace();
       }
}
   public static List<Student> readStudents(String fileName)
{
       List<Student> stuList=new ArrayList<>();
       try(ObjectInputStream ois=new ObjectInputStream(new FileInputStream("d:\\新建文本文档.txt")))
       {
           stuList=(List<Student>)ois.readObject();
           System.out.println(stuList.toString());
       }
       catch (FileNotFoundException e) {
           e.printStackTrace();
       } catch (IOException e1) {
           e1.printStackTrace();
       } catch (ClassNotFoundException e) {
           e.printStackTrace();
       }
       return stuList;
} 

我的总结

对象流可以直接对所创建的对象进行读写操作,省去了组装这步操作,但是没有缓冲流,对较大的文件操作会比较慢。

6. 正则表达式

我的代码

    Scanner sc=new Scanner(System.in);
    String str=sc.next();
    Pattern pattern=Pattern.compile("^-?[0-9]\\d*(\\.\\d+)?$");
    Matcher matcher=pattern.matcher(str);
    System.out.println(matcher.matches());
    sc.close();
import java.io.*;
import java.net.*;
import java.util.regex.*;

/**
 * This program displays all URLs in a web page by matching a regular expression that describes the
 * <a href=...> HTML tag. Start the program as <br>
 * java HrefMatch URL
 * @version 1.01 2004-06-04
 * @author Cay Horstmann
 */
public class HrefMatch
{
   public static void main(String[] args)
   {
      try
      {
         // get URL string from command line or use default
        /* String urlString;
         if (args.length > 0) urlString = args[0];
         else urlString = "http://java.sun.com";*/
         String fileName="d:\\集美大学-计算机工程学院.htm";
         // open reader for URL
        //InputStreamReader in = new InputStreamReader(new URL(urlString).openStream());
         InputStreamReader in = new InputStreamReader(new FileInputStream(fileName));
         // read contents into string builder
         StringBuilder input = new StringBuilder();
         int ch;
         while ((ch = in.read()) != -1)
            input.append((char) ch);

         String patternString = "[+-]?[0-9]+(\\.\\d+)?";
         String patternImgString = "[+-]?[0-9]+";
         Pattern pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE);
         Matcher matcher = pattern.matcher(input);

         while (matcher.find())
         {
            int start = matcher.start();
            int end = matcher.end();
            String match = input.substring(start, end);
            System.out.println(match);
         }
      }
      catch (IOException e)
      {
         e.printStackTrace();
      }
      catch (PatternSyntaxException e)
      {
         e.printStackTrace();
      }
   }
}

我的总结

1.正则表达式刚接触不是很熟悉,参考资料:
http://www.runoob.com/java/java-regular-expressions.html
https://blog.csdn.net/weixin_43860260/article/details/91417485

01-31 17:32