Java流与文件作业

0. 字节流与二进制文件

我的代码

package Test;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class TestStu {

    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);
            for (int i = 0; i < stus.length; i++)
                System.out.println(stus[i].toString());
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

class Student {
    private int id;
    private String name;
    private int age;
    private double grade;

    public Student() {

    }

    public Student(int id, String name, int age, double grade) {
        this.id = id;
        this.setName(name);
        this.setAge(age);
        this.setGrade(grade);
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        if (name.length() > 10) {
            throw new IllegalArgumentException("name's length should <=10 " + name.length());
        }
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age <= 0) {
            throw new IllegalArgumentException("age should >0 " + age);
        }
        this.age = age;
    }

    public double getGrade() {
        return grade;
    }

    public void setGrade(double grade) {
        if (grade < 0 || grade > 100) {
            throw new IllegalArgumentException("grade should be in [0,100] " + grade);
        }
        this.grade = grade;
    }

    public String toString() {
        return getClass().getName() + "[id=" + id + ",name=" + name + ",grade=" + grade + "]";
    }
}

我的总结

1.二进制文件与文本文件的区别:
文本文件只能存储char型字符变量。二进制文件可以存储char/int/short/long/float/……各种变量值。但文本文件编辑器就可以读写。比如记事本、NotePad++、Vim等。二进制文件需要特别的解码器。
2.try...catch...finally注意事项:
如果有一个catch{}语句匹配上,其他catch{}分支就不会执行了,所以catch多个异常时要注意异常写的先后顺序,总体来说父类的异常要放在越后面。在finally{}里面出现异常, 会覆盖try{}里面的异常,导致try{}里面的异常无法被捕捉到,还会导致finally{}异常后面的代码不会被执行。
3.用try..with...resouces关闭资源:
使用 try-with-resources 语句简化了finally块中的异常处理,数据流 会在 try 执行完毕后自动被关闭,前提是,这些可关闭的资源必须实现 java.lang.AutoCloseable 接口。

1.字符流与文本文件:

我的代码

public static List<Student> readStudents(String fileName){
    List<Student> studentList = new ArrayList<>();
    String fileName="d:\\student.txt";
            try(
                FileInputStream fis=new FileInputStream(fileName);
                InputStreamReader dos=new InputStreamReader(fis, "UTF-8");
                BufferedReader br=new BufferedReader(dos))
            {
                String line=null;
                while((line=br.readLine())!=null)
                {
                    String[] track=line.split("\\s+");
                    int id=Integer.parseInt(track[0]);
                    String name=track[1];
                    int age=Integer.parseInt(track[2]);
                    double grade=Double.parseDouble(track[3]);
                    Student stu=new Student(id,name,age,grade);
                    studentList.add(stu);
                }
            } 
            catch (FileNotFoundException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } 
            catch (IOException e) 
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println(studentList);
            return studentList;
            
}

我的总结

1.FileReader在读取文件的时候采取的是系统默认的编码格式, 系统默认编码格式为GBK与windows 文本文件默认编码格式不一致,所以必然会出现乱码. 想要指定自己的编码格式读取文件,那就在FileInputStream外面嵌套InputStream 来代替FileReader,之后指定编码格式即可. 读取文件用下面的代码: InputStreamReader inputStreamReader = new InputStreamReader( new FileInputStream(path),"UTF-8");
2.指定的编码格式要与文本的编码格式一致,否则还是会出现乱码,通过文件另存为指定一下编码格式即可

2.缓冲流(结合使用JUint进行测试)

我的代码

TestReader部分

package Test;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Random;
import java.util.Scanner;
public class TestReader {

        public static void main(String[] args) {
            String fileName = "d:/Test.data";
            PrintWriter pw = null;
            try {
                pw = new PrintWriter(fileName);
                Random random=new Random();
                random.setSeed(100);
                double sum=0,aver;
                for (int i = 0; i < 1000_0000; i++) {
                    int r=random.nextInt(10);
                    sum+=r;
                    pw.println(r);
                }
                aver=sum/1000_0000;
                System.out.format("%.5f", aver);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } finally {
                pw.close();
            }
        }

    }

JUNIT部分

package Test;

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

import org.junit.jupiter.api.Test;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Scanner;
class TestFileReader {
    @Test
    void testScanner() {
        Scanner scanner = null;
        String fileName = "d:/Test.data";
        try {
            scanner = new Scanner(new File(fileName));
            while (scanner.hasNextLine()) {
                scanner.nextLine();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        System.out.println("read using Scanner done");
    }

    @Test
    void testBufferedReader() {
        BufferedReader br = null;
        String fileName = "d:/Test.data";
        try {
            br = new BufferedReader(new FileReader(new File(fileName)));
            while (br.readLine() != null) {
            }
            ;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } 
        System.out.println("read using BufferedReader done");
    }

}

我的总结

1.JUNIT中要测试的方法前要加上@Test,才会出现小图标后面跟上时间
2.Java的随机数相关:相同种子数的Random对象,相同次数生成的随机数字是完全相同的;Random类中各方法生成的随机数字都是均匀分布的,也就是说区间内部的数字生成的几率均等;

3.字节流之对象流

我的代码

public static void writeStudent(List<Student> stuList)
    {
        String fileName="d:\\student.data";
        try (   FileOutputStream fos=new FileOutputStream(fileName);
                ObjectOutputStream oos=new ObjectOutputStream(fis))
        {
            oos.writeObject(stuList);
            
        } 
        catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    }
public static List<Student> readStudents(String fileName)
    {
        List<Student> stuList=new ArrayList<>();
        try (   FileInputStream fis=new FileInputStream(fileName);
                ObjectInputStream ois=new ObjectInputStream(fis))
        {
            stuList=(List<Student>)ois.readObject();
        } 
        catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return stuList;
}   

我的总结

1.使用对象流读取数据时,不是之前Scanner等一行一行的读取,而是读入整个对象,可能是以集合或者数组的形式读入
2.当使用对象流写入或者读取对象的时候,必须保证该对象是序列化的,这样是为了保证对象能够正确的写入文件,并能够把对象正确的读回程序。

5.文件操作

我的代码

package Test;

import java.io.*;
import java.nio.file.*;

public class Main {
    // TODO Auto-generated method stub
    Path dir=Paths.get("d:\\", "testStream","36");
    findFile(dir,"test.txt");
}
public static void findFile(Path dir,String fileName)
{
    File file=dir.toFile();
    File[] files=file.listFiles();
    for(File txt:files)
    {
        if(txt.isFile())
        {
            if(txt.getName().equals(fileName))
            {
                System.out.println(txt.getAbsolutePath());
                return;
            }
        }
        else if(txt.isDirectory())
        {
            findFile(txt.toPath(),fileName);
        }
    }
}
}

我的总结

(1)采用递归形式完成,还能利用队列进行搜索
(2)Paths类获取文件或文件目录路径可以使用采用多个字符串形式,也可以使用Path.get(D:\ReviewIO\URL)这种形式。返回的Path对象完全可以代替File类用于文件IO操作。
(3)File类的方法参数很多,要使用泛型为字符类型的集合类作为数据写入指定文件中。

6.正则表达式

我的代码

(1)判断一个给定的字符串是否是10进制数字格式

package Test;

import java.util.*;
import java.util.regex.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        Pattern pattern=Pattern.compile("^[+-]?[0-9]+(\\.\\d+)?");
        Matcher matcher=null;
        while(sc.hasNext())
        {
            String testStr=sc.next();
            matcher=pattern.matcher(testStr);
            System.out.println(matcher.matches());
        }
        sc.close();
    }
}

我的总结

1.详细了解正则表达式的使用方法,能够灵活运用,代码中使用的“^[+-]?[0-9]+(\.\d+)?”花费了一段时间才写出来
2.Pattern类用于创建一个正则表达式,也可以说是创建一个匹配模式;Pattern类中的matcher(CharSequence input)会返回一个Matcher对象,Matcher类提供了对正则表达式的分组支持,以及对正则表达式的多次匹配支持。
3.要想得到更丰富的正则匹配操作,那就需要将Pattern与Matcher联合使用。

(2)匹配网页中的数字字符串

package Test;

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 = "https://pintia.cn";
             */
            String fileName = "D:\\test\\集美大学-计算机工程学院.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);

            // search for all occurrences of pattern
            String patternString = "<a\\s+href\\s*=\\s*(\"[^\"]*\"|[^\\s>]*)\\s*>";
            String patternImgString = "[+-]?[0-9]+";
            // String patternString = "[\u4e00-\u9fa5]"; //匹配文档中的所有中文
            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.出现了fileName (系统找不到指定的文件。)的异常,百度搜索后发现要在父目录下建立子目录,再将指定文件加入子目录,就能成功找到。
2.除了使用“^-?[0-9]+”这个正则表达式来匹配数字字符串,还可以使用“^-?\d+(\.\d+)?$”,效果相同。

猜你喜欢

转载自www.cnblogs.com/ggad/p/11937867.html