当前位置: 首页 > news >正文

java中的IO流

IO流

  • 1、File类
    • 1.1 获取文件或目录信息
    • 1.2 操作文件
    • 1.3 操作目录
    • 1.4 案例:递归列出目录的下一级
    • 1.5 案例:递归列出目录下的所有Java源文件
  • 2、IO流的分类和设计
    • 2.1 输出纯文本数据
    • 2.2 读取纯文本数据
    • 2.3 按行读取
    • 2.4 复制文件基本版
    • 2.5 复制文件提升效率版
    • 2.6 操作Java各种数据类型的数据
    • 2.7 保存对象
      • 2.7.1 序列化和反序列化
      • 2.7.2 不序列化的属性
      • 2.7.3 序列化版本ID
    • 2.8 按行输出文本内容
    • 2.9 Scanner类与IO流

1、File类

  java.io包下有一个File类,File就是文件或文件夹。API中File的解释是文件和目录路径名的抽象表示形式,即通过指定路径名称来表示磁盘或网络中的某个文件或目录。也就是说,程序中的文件和目录都可以通过File类的对象来完成,如新建、删除、重命名文件和目录等。

  另外,程序不能直接通过File对象读取内容或写入数据,如果要操作数据,则必须通过IO流。

1.1 获取文件或目录信息

  File类常用方法一如下:

序号方法名描述
1String getName()返回此File对象所表示的文件或目录名(返回最后一级)
2String getPath()返回此File对象所对应的路径名
3String getAbsolutePath()返回此File对象所对应的绝对路径名
4String getCanonicalPath()返回此File对象对应的规范路径名
5String getParent()返回此File对象的父目录名
6File getParentFile()返回此File对象的父目录名所对应的File对象

  用File对象表示文件,并获取文件的相关路径信息:

import java.io.File;
import java.io.IOException;

public class FileTest1 {
    public static void main(String[] args) throws IOException {
        File file = new File("../chap12ConnectionAndMap.ListAddTest");
        System.out.println("user.dir="+System.getProperty("user.dir"));
        System.out.println("文件/目录的名称:"+file.getName());
        System.out.println("文件/目录的路径名:"+file.getPath());
        System.out.println("文件/目录的绝对路径名:"+file.getAbsolutePath());
        System.out.println("文件/目录的规范路径名:"+file.getCanonicalPath());
        System.out.println("文件/目录的父目录名:"+file.getParent());
        System.out.println("文件/目录的父目录对象:"+file.getParentFile());
    }
}

image-20220926205221367

  File类的常用方法二:

序号方法名描述
1boolean exists()判断File对象对应的文件或目录是否存在
2boolean canRead()判断File对象对应的文件或目录是否可读
3boolean canWrite()判断File对象对应的文件或目录是否可写
4boolean isHidden()判断File对象对应的文件或目录是否隐藏
5boolean isFile()判断File对象对应的是否是文件
6boolean isDirectory()判断File对象对应的是否是目录
7long lastModified()返回File对象对应的文件或目录的最后修改时间(毫秒值)
8long length()返回File对象对应的文件的内容的长度(字节数),如果File对象对应的是目录,则结果是不确定的

  如果new的File对象所表示的文件或目录并不存在,那么并不会应位new了一个File对象,操作系统就在对应的路径下创建所对应的文件和目录,它仅仅是在JVM的堆中new了一个File对象而已。此时通过File对象获取的所有属性都是对象属性的默认值,如length()返回为0,isFile()和isDirectory()返回为false等。

  示例代码:

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

public class FileTest2 {
    public static void main(String[] args) {
        File file = new File("F:\\IDEA_test\\剑指Java\\src\\chap13File\\test.java");
        long time = file.lastModified();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
        String format = sf.format(new Date(time));
        System.out.println("最后修改时间:"+format);
        System.out.println("文件大小:"+file.length());
    }
}

image-20220926205857590

1.2 操作文件

  我们在java程序中new了一个File对象,仅仅是在JVM的堆中创建了一个实例对象,并不会导致操作系统在对应路径下创建一个文件。如果希望在对应路径下创建或删除一个文件,那么需要使用如下表格中的方法。

  File类的常用方法三:

序号方法名描述
1boolean createNewFile()如果指定的文件不存在并创建成功,返回true;如果指定的文件已存在,返回false;
2boolean createTempFile(String prefix,String suffix)在默认临时文件的目录中创建一个空文件,给定前缀和后缀生成其名称,调用此方法等同于调用createTempFile(prefix,suffix,null)
3boolean delete()当且仅当成功删除文件时,返回true;否则返回false
4void deleteOnExit()当退出JVM时,删除文件,一般用于删除临时文件
5boolean renameTo(File dest)重命名

  创建新文件

import java.io.File;
import java.io.IOException;

public class TestCreateFile {
    public static void main(String[] args) throws IOException {
        File file = new File("F:\\IDEA_test\\剑指Java\\src\\chap13File\\test.java");
        //创建新文件
        file.createNewFile();

    }
}

  创建临时新文件:

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

        //创建临时新文件
        File tempFile = File.createTempFile("hello", ".tmp");
        System.out.println(tempFile.getAbsolutePath());
    }
}

  删除文件

public class TestDeleteFile {
    public static void main(String[] args) {
        File file = new File("F:\\IDEA_test\\剑指Java\\src\\chap13File\\test.java");
        //删除文件
        file.delete();
    }
}

  重命名一个文件或目录

import java.io.File;

public class TestRenameFile {
    public static void main(String[] args) {
        File src = new File("F:\\IDEA_test\\剑指Java\\src\\chap13File\\test.txt");
        File dest = new File("F:\\IDEA_test\\剑指Java\\src\\chap13File\\testFile.txt");
        src.renameTo(dest);

    }
}

1.3 操作目录

  以下是操作目录的常见方法,

序号方法名描述
1boolean mkdir()必须确保父目录存在,否则创建失败
2boolean mkdirs()如果父目录链不存在,则会一同创建父目录链
3String[] list()列出当前目录的下级目录或文件的名称
4File[] listFiles()列出当前目录的下级目录或文件对应的File对象
5File[] listFiles(FileFilter filter)返回抽象路径名数组,返回所有满足指定过滤器的文件和目录
6File[] listFiles(FilenameFilter filter)返回抽象路径名数组,返回所有满足指定过滤器的文件和目录
7static File[] listRoots()列出可用的文件系统根
8boolean delete()只能删除空目录。否则需要先将目录下的所有内容删除才能将该目录删除
9boolean renameTO(File dest)如果是Windos目录,则只能在同一个盘下,不能从D盘移动到E盘

  创建一级目录

public class TestCreateDirectory {
    public static void main(String[] args) {
        File dir = new File("F:\\codeleader\\javase\\io");
        dir.mkdir();
    }
}

  创建多级目录

public class TestCreateDirectorys {
    public static void main(String[] args) {
        File dir = new File("F:\\codeleader\\javase\\io");
        dir.mkdirs();
    }
}

   如果父目录不存在,那么会一并创建,当然F盘分区是必须存在的,否则无法创建成功。

  列出目录内容

public class TestListFiles {
    public static void main(String[] args) {
        File dir = new File("f:\\codeleader");
        File[] listFiles = dir.listFiles();
        if(listFiles!=null){
            for (int i = 0; i < listFiles.length; i++) {
                System.out.println(listFiles[i]);
            }
        }
    }
}

image-20220926211314563

  列出目录内容,并加入过滤条件:

  列出目录下的所有.java文件

public class TestFileFilter {
    public static void main(String[] args) {
        File dir = new File("F:\\IDEA_test\\剑指Java\\src\\chap13File");
        File[] listFiles = dir.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {

                return name.endsWith(".java");
            }
        });

        if(listFiles!=null){
            for (File sub : listFiles) {
                System.out.println(sub);
            }
        }
    }
}

image-20220926211404083

  删除目录

public class TestDeleteDirectory {
    public static void main(String[] args) {
        File dir = new File("F:\\codeleader\\javase\\io");
        dir.delete();
    }
}

  目录重命名

public class TestRenameDirectory {
    public static void main(String[] args) {
        File dir = new File("F:\\codeleader\\javase");
        File dest = new File("F:\\codeleader\\javacode");
        dir.renameTo(dest);
    }
}

  上述代码将F:/codeleader目录下的javase重命名为javacode

1.4 案例:递归列出目录的下一级

  案例需求:列出某个目录(文件夹)下所有的下一级,如果下一级仍然是一个目录(文件夹),那么就继续列出它的下一级知道最后一级。

  方案一:直接打印输出,不返回。

public class TestListAllSubs {
    public static void main(String[] args) {
        File dir = new File("F:\\codeleader");
        listSubFiles(dir);
    }
    public static void listSubFiles(File dir){
        if(dir!=null&&dir.isDirectory()){
            File[] listFiles = dir.listFiles();
            if(listFiles!=null){
                for (File sub : listFiles) {
                    listSubFiles(sub);      //递归调用
                }
            }
        }
        System.out.println(dir);
    }
}

image-20220926211752676

  方案二:使用集合返回所有下一级,并考虑异常处理。

public class TestListAllSubs2 {
    public static void main(String[] args) {
        File dir = new File("F:\\codeleader");
        try {
            ArrayList<File> all = listSubFiles(dir);
            for (File file : all) {
                System.out.println(file);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    //列出某个目录下的所有下一级子目录或子文件
    public static ArrayList<File> listSubFiles(File dir) throws FileNotFoundException,IllegalArgumentException {
        if(dir==null||!dir.exists()){
            throw new FileNotFoundException(dir+"不存在");
        }
        if(dir.isFile()){
            throw new IllegalArgumentException(dir+"不是一个目录");
        }
        ArrayList<File> all = new ArrayList<>();
        if(dir!=null&& dir.isDirectory()){
            File[] listFiles = dir.listFiles();
            if(listFiles!=null){
                for (File sub : listFiles) {
                    all.add(sub);
                    if(sub.isDirectory()){
                        all.addAll(listSubFiles(sub));//递归调用
                    }
                }
            }
        }
        return all;
    }
}

image-20220926211836963

1.5 案例:递归列出目录下的所有Java源文件

public class TestListAllJavaFiles {
    public static void main(String[] args) {
        File dir = new File("F:\\IDEA_test\\剑指Java\\src\\chap13File\\dirs");
        listByFileFilter(dir);
    }

    public static void listByFileFilter(File file){
        if(file!=null && file.isDirectory()){
            File[] listFiles = file.listFiles(new FileFilter() {
                @Override
                public boolean accept(File pathname) {
                    return pathname.isDirectory() || pathname.getName().endsWith(".java");
                }
            });
            if(listFiles!=null){
                for (File sub : listFiles) {
                    if(sub.isFile()){//如果是文件就直接输出
                        System.out.println(sub);
                    }else{//如果是文件夹目录,就递归
                        listByFileFilter(sub);
                    }
                }
            }
        }
    }
}

image-20220926212037429

2、IO流的分类和设计

  IO流的四个超级父类、抽象基类:

  • InputStream:字节输入流,以字节方式读取数据。
  • OutputStream:字节输出流,以字节的方式输出数据。
  • Reader:字符输入流,以字符的方式读取数据。
  • Writer:字符输出流,以字符的方式输出数据。

2.1 输出纯文本数据

  案例需求:用键盘输入文本留言信息,并保存到message.txt文件中。

public class FileWriterTest {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        FileWriter fw=null;

        try {
            //true表示追加模式,默认是覆盖模式
            fw=new FileWriter("F:\\IDEA_test\\剑指Java\\src\\chap13File\\IO\\message.txt",true);

            while(true){
                System.out.println("请输入留言(stop结束):");
                String message = input.nextLine();//输入

                if("stop".equals(message)){
                    break;
                }
                fw.write(message);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(input!=null){
                input.close();
            }
            try {
                if (fw!=null) {
                    fw.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

image-20220926212452813

image-20220926212501659

2.2 读取纯文本数据

  案例需求:从message.txt中读取用户留言信息。

public class FileReaderTest {
    public static void main(String[] args) {
        FileReader fr=null;
        try {
            fr = new FileReader("F:\\IDEA_test\\剑指Java\\src\\chap13File\\IO\\message.txt");

            char[] data=new char[1024];
            int len;
            //每次read,将数据读入到data数组中,并返回读入data中字符的个数
            //如果是行尾,则返回-1
            while((len=fr.read(data))!=-1){
                System.out.println(new String(data,0,len));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            if(fr!=null){
                try {
                    fr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

image-20220926212543395

2.3 按行读取

  案例需求:从message.txt文件中读取用户留言信息,要求按行读取留言消息。

  分析:message.txt是纯文本文件,首先考虑的肯定是Reader系列的FileReader类。但是FileReader类没有办法实现按行读取,所以需要其他的IO流来协助,如BufferedReader类的readLine方法,Scanner类的nextLine方法。

public class BufferedReaderTest {
    public static void main(String[] args) {
        BufferedReader br=null;
        try {
            br=new BufferedReader(new FileReader("F:\\IDEA_test\\剑指Java\\src\\chap13File\\IO\\message.txt"));
            String str;
            //按行读取,每次读取一行数据。如果是行尾,则返回null
            while((str=br.readLine())!=null){
                System.out.println(str);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(br!=null){
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

image-20220926212931038

   注意:只有纯文本的数据才支持按行读取。

2.4 复制文件基本版

  和文件独写相关的IO流一共有以下四个:

  • 文件字节输入流:FileInputStream
  • 文件字节输出流:FileOutputStram
  • 文件字符输入流:FileReader
  • 文件字符输出流:FileWriter
public class CopyTest {
    public static void main(String[] args) {
        try {
            copyFile(new File("F:\\IDEA_test\\剑指Java\\src\\chap13File\\IO\\1.png"),new File("F:\\IDEA_test\\剑指Java\\src\\chap13File\\IO\\test\\1.png"));
            System.out.println("文件复制成功");
        } catch (IOException e) {
            System.out.println("文件复制失败");
            e.printStackTrace();
        }
    }

    //复制文件
    public static void copyFile(File src,File dest) throws IOException{
        FileInputStream fis = new FileInputStream(src);
        FileOutputStream fos = new FileOutputStream(dest);

        try {
            byte[] data = new byte[1024];
            int len;
            while((len=fis.read(data))!=-1){//读取
                fos.write(data,0,len);//写入
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(fis!=null){
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                if(fos!=null){
                    fos.close();
                }
            }
        }
    }
}

  上述代码实现了图片的复制

2.5 复制文件提升效率版

  java.io包提供了Buffered系列的缓冲流,可以在独写数据时提升效率;Buffered系列的IO流只能给对应类型的IO流增加缓冲功能。例如,BufferedInputStream可以给InputStream系列的IO流增加缓冲功能,BufferedReader可以给Reader系列的IO流增加缓冲功能。

public class BufferedCopyTest {
    public static void main(String[] args) {
        try {
            copyFileInHighSpeed(new File("F:\\IDEA_test\\剑指Java\\src\\chap13File\\IO\\ig.jpg"),new File("F:\\IDEA_test\\剑指Java\\src\\chap13File\\IO\\test\\ig.jpg"));
            System.out.println("文件复制成功");
        } catch (IOException e) {
            System.out.println("文件复制失败");
            e.printStackTrace();
        }
    }

    //复制文件-带缓冲功能
    public static void copyFileInHighSpeed(File src,File dest) throws IOException {
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(src));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(dest));
        try {
            byte[] data = new byte[1024];
            int len;
            while((len=bis.read(data))!=-1){//读取
                bos.write(data,0,len);//写入
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(bis!=null){
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }finally {
                    if(bos!=null){
                        bos.close();
                    }
                }
            }
        }
    }
}

  缓冲流的工作原理是先将要读取或写出的数据缓存到缓冲流的缓冲区,而缓冲区在JVM内存中,这样就减少了JVM内存与外接设备的交互次数,从而可以提高读写效率。

2.6 操作Java各种数据类型的数据

  可以使用DataOutputStream把数据写入文件,随后用DataInputStream进行读取,而且读取和写入的顺序要完全一致。

public class DataTest {
    public static void main(String[] args) throws IOException {
        save();
        reload();
    }
    //写入数据
    public static void save() throws IOException {
        String name="巫师";
        int age=300;
        char gender='男';
        int energy=5000;
        double price=75.5;
        boolean relive=true;
        DataOutputStream dos = new DataOutputStream(new FileOutputStream("F:\\IDEA_test\\剑指Java\\src\\chap13File\\dataExer\\game.dat"));
        dos.writeUTF(name);
        dos.writeInt(age);
        dos.writeChar(gender);
        dos.writeInt(energy);
        dos.writeDouble(price);
        dos.writeBoolean(relive);
        dos.close();
    }
    //读取数据
    public static void reload() throws IOException {
        DataInputStream dis = new DataInputStream(new FileInputStream("F:\\IDEA_test\\剑指Java\\src\\chap13File\\dataExer\\game.dat"));
        try {
            String name = dis.readUTF();
            int age = dis.readInt();
            char gender = dis.readChar();
            int energy = dis.readInt();
            double price = dis.readDouble();
            boolean relive = dis.readBoolean();

            System.out.println(name+","+age+","+gender+","+energy+","+price+","+relive);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(dis!=null){
                dis.close();
            }
        }
    }
}

2.7 保存对象

2.7.1 序列化和反序列化

  Java中输出对象的过程称为序列化,读取对象的过程称为反序列化

  序列化的过程需要使用ObjectOutputStream,它有一个writeObject(obj)方法可以输出对象,即将对象的完整信息转换为字节流数据。

  反序列化的过程需要使用ObjectInoutStream,它有一个readObject()方法可以读取对象,即从字节流数据中读取信息并重构一个java对象。

import java.io.Serializable;

public class Account implements Serializable {
    private static double interestRate;//利率
    private String number;  //账号
    private String name;//户主
    private String password;//密码
    private double balance;//余额

    public Account(String number, String name, String password, double balance) {
        this.number = number;
        this.name = name;
        this.password = password;
        this.balance = balance;
    }

    public static double getInterestRate() {
        return interestRate;
    }

    public static void setInterestRate(double interestRate) {
        Account.interestRate = interestRate;
    }

    @Override
    public String toString() {
        return "Account{" +
                "number='" + number + '\'' +
                ", name='" + name + '\'' +
                ", password='" + password + '\'' +
                ", balance=" + balance +
                '}';
    }
}
public class ObjectOutputStreamTest {
    public static void main(String[] args) throws IOException {
        Account.setInterestRate(0.0024);
        Account account = new Account("111000111", "codeleader", "123456", 1000.0);
        ObjectOutputStream oos=null;
        try {
            oos = new ObjectOutputStream(new FileOutputStream("F:\\IDEA_test\\剑指Java\\src\\chap13File\\serializable\\account.dat"));
            oos.writeObject(account);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(oos!=null){
                oos.close();
            }
        }

    }
}

  打开account.dat文件发现,序列化后的文件很难让人阅读,没关系,只有使用java程序才能读取序列化后的数据。

  示例代码:

public class ObjectInputStreamTest {
    public static void main(String[] args) throws IOException {
        ObjectInputStream ois=null;
        try {
            ois = new ObjectInputStream(new FileInputStream("F:\\IDEA_test\\剑指Java\\src\\chap13File\\serializable\\account.dat"));
            Object readObject = ois.readObject();//读取对象
            System.out.println(readObject);
            System.out.println(Account.getInterestRate());

        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }finally {
            if(ois!=null){
                ois.close();
            }
        }
    }
}

image-20220926214252133

   可以看到,正确地将account.dat中的数据反序列化回来了。但是发现利率值是不对的,因为它被static修饰,它不会被序列化。

2.7.2 不序列化的属性

  类中static修饰的静态变量值是不会序列化的。

  如果有些变量不需要被序列化,可以标记为transient(瞬时)。被标记为transient的对象在反序列化时,会被恢复为默认值。

2.7.3 序列化版本ID

  序列化时的类与反序列化时的类不一致,会报异常。java为了避免这种类型安全性问题的发生,使序列化接口类在每次编译时,自动生成一个序列化版本ID,用以区别不同的版本,当序列化和反序列化的版本不一致时,就会失败,抛出异常java.io.InvalidClassException

  然而,有些修改并不影响对象的反序列化,如类中加入了新的实例变量,而序列化的数据中并没有新实例变量的值,那么它在反序列化的过程中可以使默认值。为了适应这种情况,我么你在实现java.io.Serializable接口时,给类增加一个long类型的静态常量serialVersionUID,这样在对类进行修改后重新编译时系统并不会自动生成序列化版本ID,只要serialVersionUID没有修改,那么原来序列化的数据也可以顺利反序列化。

  Account类增加序列化版本ID.

public class Account implements Serializable {
    private static final long serialVersionUID=1L;//序列化版本ID[唯一标识]

    private static double interestRate;//利率
    private String number;  //账号
    private String name;//户主
    private String password;//密码
    private double balance;//余额

    public Account(String number, String name, String password, double balance) {
        this.number = number;
        this.name = name;
        this.password = password;
        this.balance = balance;
    }

    public static double getInterestRate() {
        return interestRate;
    }

    public static void setInterestRate(double interestRate) {
        Account.interestRate = interestRate;
    }

    @Override
    public String toString() {
        return "Account{" +
                "number='" + number + '\'' +
                ", name='" + name + '\'' +
                ", password='" + password + '\'' +
                ", balance=" + balance +
                '}';
    }
}

2.8 按行输出文本内容

  PrintStreamPringWriter是两个打印流,可以实现将java基本数据类型的数据格式转化为字符串输出,引用类型的数据自动调用toString()方法。

  案例需求:从键盘中输入消息,按行写入文件。

import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Scanner;

public class PrintWriterTest {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        PrintWriter pw=null;
        try {
            pw = new PrintWriter("F:\\IDEA_test\\剑指Java\\src\\chap13File\\demo\\message.txt");
            while(true){
                System.out.println("请输入留言:");
                String message = input.nextLine();//按行输入

                if("stop".equals(message)){
                    break;
                }
                pw.println(message);
                System.out.println("结束留言,请输入stop");
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            if(input!=null){
                input.close();
            }
            if(pw!=null){
                pw.close();
            }
        }
    }
}

image-20220926215243849

image-20220926215252506

2.9 Scanner类与IO流

  java.util.Scanner是一个可以使用正则表达式来解析基本数据类型和字符串的简单文本扫描器。

  案例需求:使用Scanner在控制台接收用键盘输入的各种类型数据。

public class ScannerSystemInTest {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.println("姓名:");
        String name = input.nextLine();
        System.out.println("性别:");
        char gender = input.next().charAt(0);
        System.out.println("年龄:");
        int age = input.nextInt();
        System.out.println("电话:");
        String phone = input.next();
        System.out.println("邮箱:");
        String email = input.next();
        System.out.println("姓名:"+name);
        System.out.println("性别:"+gender);
        System.out.println("年龄:"+age);
        System.out.println("电话:"+phone);
        System.out.println("邮箱:"+email);

    }
}

image-20220926215502676

  案例需求:使用Scanner从文件中扫描数据。

public class ScannerFromFileTest {
    public static void main(String[] args) throws IOException {
        FileInputStream fileInputStream=null;
        Scanner input=null;
        try {
            fileInputStream = new FileInputStream("F:\\IDEA_test\\剑指Java\\src\\chap13File\\System\\info.txt");
            input = new Scanner(fileInputStream);
            while(input.hasNext()){
                String str = input.nextLine();
                System.out.println(str);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            if(input!=null){
                input.close();
            }
            if(fileInputStream!=null){
                fileInputStream.close();
            }
        }
    }
}

image-20220926215551616

image-20220926215622673

  这块的API实在是太多了,上面也只是接触到了点皮毛,更多的细节操作只有在生产中发掘了。

相关文章:

  • 【每日一练】图解: 数组中的逆序对
  • 【Django】开发日报_8_Day:手机号码管理系统(6)
  • Quartz框架之Job和JobDetail(2)
  • C语言刷题(二)
  • 【毕业设计】机器学习股票大数据量化分析与预测系统 - python 毕业设计
  • Ubuntu下安装opencv
  • 手把手带你刷好题(牛客刷题⑦)
  • Java保证线程安全的方式有哪些?
  • 《数据结构》队列及其经典面试题
  • 计算机图形学(十一):真实感图形(光照模型、材质模型)
  • 【云原生】Hadoop HA on k8s 环境部署
  • 四元数是什么
  • 大衣哥家里再添喜事,生产厂家免费送给他一辆新车
  • 爬取疫情数据并存到mysql数据库
  • 场景应用:网络的子网掩码为255.255.240.0,它能够处理的主机数是多少?
  • 【干货分享】SpringCloud微服务架构分布式组件如何共享session对象
  • Angular js 常用指令ng-if、ng-class、ng-option、ng-value、ng-click是如何使用的?
  • Babel配置的不完全指南
  • CentOS7 安装JDK
  • ECMAScript 6 学习之路 ( 四 ) String 字符串扩展
  • Javascript 原型链
  • Js基础知识(四) - js运行原理与机制
  • Nodejs和JavaWeb协助开发
  • PHP的类修饰符与访问修饰符
  • Redis的resp协议
  • 阿里研究院入选中国企业智库系统影响力榜
  • 第十八天-企业应用架构模式-基本模式
  • 翻译 | 老司机带你秒懂内存管理 - 第一部(共三部)
  • 关于Java中分层中遇到的一些问题
  • 紧急通知:《观止-微软》请在经管柜购买!
  • 前端之Sass/Scss实战笔记
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 什么软件可以提取视频中的音频制作成手机铃声
  • 使用权重正则化较少模型过拟合
  • 消息队列系列二(IOT中消息队列的应用)
  • 运行时添加log4j2的appender
  • 06-01 点餐小程序前台界面搭建
  • [Shell 脚本] 备份网站文件至OSS服务(纯shell脚本无sdk) ...
  • [地铁译]使用SSD缓存应用数据——Moneta项目: 低成本优化的下一代EVCache ...
  • 微龛半导体获数千万Pre-A轮融资,投资方为国中创投 ...
  • #Linux(make工具和makefile文件以及makefile语法)
  • (C++)栈的链式存储结构(出栈、入栈、判空、遍历、销毁)(数据结构与算法)
  • (C语言)字符分类函数
  • (二)什么是Vite——Vite 和 Webpack 区别(冷启动)
  • (附源码)springboot 校园学生兼职系统 毕业设计 742122
  • (论文阅读23/100)Hierarchical Convolutional Features for Visual Tracking
  • (三)docker:Dockerfile构建容器运行jar包
  • (转)大型网站架构演变和知识体系
  • (转)用.Net的File控件上传文件的解决方案
  • .NET Core实战项目之CMS 第十二章 开发篇-Dapper封装CURD及仓储代码生成器实现
  • .net 程序发生了一个不可捕获的异常
  • .NET 使用 ILMerge 合并多个程序集,避免引入额外的依赖
  • .NET/C# 利用 Walterlv.WeakEvents 高性能地定义和使用弱事件
  • .NET/C# 中设置当发生某个特定异常时进入断点(不借助 Visual Studio 的纯代码实现)
  • .NET简谈设计模式之(单件模式)