java高级-续1

IO

所谓IO就是输出输出(input/output)。一般的理解都是相对于计算机而言的输入输出。

比如:

输出设备:显示器,耳机,音响,打印机…..

输入设备:键盘,鼠标,麦克风……

上面的所有的输入输出都是相对于计算机而言的。

我们这里说的输入输出是相对于内存而言的

  • 数据读取到内存就是输入。
  • 数据从内存写出就是输出。

输入输出的原理:

java高级-续1

输出的数据流称之为输出流,输入的数据流称之为输入流。

面试题:java的流是如何分类的? 按照方向分为:输入流和输出流。 按照处理方式:分为字节流和字符流。

java高级-续1

java高级-续1

File类

在java.io包下有一个File。 这个类的所有对象都表示一个文件。(一个File类的对象就是一个文件或者文件夹的抽象表示)

内部的常量

  • static String pathSeparator 与系统相关的路径分隔符字符,为方便起见,表示为字符串。
  • static char pathSeparatorChar 与系统相关的路径分隔符。
  • static String separator 与系统相关的默认名称 – 分隔符字符,以方便的方式表示为字符串。
  • static char separatorChar 与系统相关的默认名称分隔符。

前面两个常量是路径相关的分隔符。后面两个是名称分隔符。

以前在linux中分隔符是 "/" 在windows中是 "\"

构造方法

  • File(File parent, String child) 从父抽象路径名和子路径名字符串创建新的 File实例。
  • File(String pathname) 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。
  • File(String parent, String child) 从父路径名字符串和子路径名字符串创建新的 File实例。
  • File(URI uri) 通过将给定的 file: URI转换为抽象路径名来创建新的 File实例。
相对路径和绝对路径。 所谓相对路径,就是相对于当前的文件而言,目标的位置。 所谓绝对路径,就是从盘符开始的路径。 一般建议使用相对路径。

undefined

File类的一些API:

获取信息的—

  • exists()测试此抽象路径名表示的文件或目录是否存在。
  • getName() 返回由此抽象路径名表示的文件或目录的名称。
  • getAbsolutePath()返回此抽象路径名的绝对路径名字符串。
  • getParent() 返回此抽象路径名的父 null的路径名字符串,如果此路径名未命名为父目录,则返回null。
  • getParentFile() 返回此抽象路径名的父,或抽象路径名 null如果此路径名没有指定父目录。
  • isDirectory()测试此抽象路径名表示的文件是否为目录。
  • isFile()测试此抽象路径名表示的文件是否为普通文件。
  • lastModified() 返回此抽象路径名表示的文件上次修改的时间。
  • length() 返回由此抽象路径名表示的文件的长度。
  • list() 返回一个字符串数组,命名由此抽象路径名表示的目录中的文件和目录。
  • listFiles() 返回一个抽象路径名数组,表示由该抽象路径名表示的目录中的文件。

案例:

undefined

我们查看文件的大小,从现在开始都是看字节:

java高级-续1
1B byte = 8bit 1K = 1024B 1M = 1024K 1G = 1024M 1T = 1024G 1P = 1024T

创建删除判断的一些API—-

  • canExecute() 测试应用程序是否可以执行此抽象路径名表示的文件。
  • canRead() 测试应用程序是否可以读取由此抽象路径名表示的文件。
  • canWrite() 测试应用程序是否可以修改由此抽象路径名表示的文件。
  • delete() 删除由此抽象路径名表示的文件或目录。
  • boolean mkdir() 创建由此抽象路径名命名的目录。
  • boolean mkdirs() 创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录。
  • createNewFile() 当且仅当具有该名称的文件尚不存在时,原子地创建一个由该抽象路径名命名的新的空文件。

异常问题:

java高级-续1

案例:

undefined

字节输入流InputStream

所有的字节输入流的老祖宗就是 java.io.InputStream。

字节流的特点:是以字节的方式处理数据

这个类是一个抽象类,其目的就是为了让其他的类实现。所以我们都是使用这个类的子类。

浏览API:

  • int available() 返回从该输入流中可以读取(或跳过)的字节数的估计值,而不会被下一次调用此输入流的方法阻塞。 (这个方法对于网络流是无效的)
  • void close() 关闭此输入流并释放与流相关联的任何系统资源。
  • void mark(int readlimit) 标记此输入流中的当前位置。
  • boolean markSupported() 测试这个输入流是否支持 mark和 reset方法。
  • abstract int read() 从输入流读取数据的下一个字节。
  • int read(byte[] b) 从输入流读取一些字节数,并将它们存储到缓冲区 b 。
  • int read(byte[] b, int off, int len) 从输入流读取最多 len字节的数据到一个字节数组。
  • void reset() 将此流重新定位到上次在此输入流上调用 mark方法时的位置。
  • long skip(long n) 跳过并丢弃来自此输入流的 n字节数据。

FileInputStream–InputStream的实现类

构造方法:

  • FileInputStream(File file) 通过打开与实际文件的连接创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。
  • FileInputStream(String name) 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。

API:就是参考父类的API。

使用:按照单个的字节读取数据。

undefined

输入流还提供了一些API可以按组读取数据

按组读取数据的API-1:

public class FileInputStreamTest1 {
    public static void main(String[] args) {
        // 通过文件名构建一个字节输入流
        InputStream in = null;
        try {
            // 根据文件创建输入流
            File file = new File("names.txt");
            in = new FileInputStream(file);
            // 按组读取
            // int read(byte[] b)读取最多b.length字节的数据到字节数组    返回值实际读取的长度。如果到达文件末尾返回-1
            // 准备一个字节数组
            byte [] buff = new byte[500];
            // 读取数据到缓冲数组
            int len = in.read(buff);
            System.out.println("实际读取的长度是:"+len);
            String str = new String(buff);// 根据整个数组创建字符串
            System.out.println(str);
            System.out.println("--------------");
            // 根据实际读取的字节长度创建字符串
            //(字节数组,偏移量,使用长度)
            String info = new String(buff,0,len);
            System.out.println(info);
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try{
                if(in!=null){
                    in.close();
                }
            }catch (IOException ex){
                ex.printStackTrace();
            }
        }
    }
}

按组读取数据API-2:

undefined

实际应用中读取文件:

上面的按组读取的例子中,都是一次性将所有的数据读取到内存中。

如果一个文件有一个T,我们肯定无法一次性读取到内存。

解决方案:按组,循环读取,重复使用缓冲数组。

看程序:

undefined

字节输出流OuputStream

OuputStream是所有的字节输出流的老祖宗。

API:

  • void close() 关闭此输出流并释放与此流相关联的任何系统资源。
  • void flush()刷新此输出流并强制任何缓冲的输出字节被写出。
  • void write(byte[] b) 将 b.length字节从指定的字节数组写入此输出流。
  • void write(byte[] b, int off, int len) 从指定的字节数组写入 len个字节,从偏移 off开始输出到此输出流。
  • abstract void write(int b) 将指定的字节写入此输出流。

FileOutputStream–OutputStream的实现类

  • FileOutputStream(File file) 创建文件输出流以写入由指定的 File对象表示的文件。
  • FileOutputStream(File file, boolean append) 创建文件输出流以写入由指定的 File对象表示的文件。
  • FileOutputStream(String name) 创建文件输出流以指定的名称写入文件。
  • FileOutputStream(String name, boolean append) 创建文件输出流以指定的名称写入文件。

api就是父类中的方法。

构造方法案例:

public class FileOutputStreamTest1 {
    public static void main(String[] args) {
        // 申明字节输出流
        OutputStream out = null;
        try{
            // 创建流
            // 根据文件创建输出流
            File file = new File("st.txt");
            // 从文件开头开始写数据。 覆盖了原有的数据
            out = new FileOutputStream(file);
            // 根据文件创建输出流
            // append:
            //  true 从文件的末尾开始写,续在文件原有数据的后面。
            //  false  从文件的开头开始写,覆盖原有数据
            out = new FileOutputStream(file,true);
            // 根据文件名创建输出流
            // 从文件开头开始写数据。 覆盖了原有的数据
            out = new FileOutputStream("hell.txt");
            // append:
            //  true 从文件的末尾开始写,续在文件原有数据的后面。
            //  false  从文件的开头开始写,覆盖原有数据
            out = new FileOutputStream("hell.txt",true);
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try{
                if(out!=null){
                    out.close();
                }
            }catch (IOException ex){
                ex.printStackTrace();
            }
        }
    }
}

tips:如果我们创建的输出流指向的文件不存在,当我们写出数据的时候会自动创建这个文件。

三个写数据的API:

输出一个字节:

public class FileOutputStreamTest1 {
    public static void main(String[] args) {
        // 申明字节输出流
        OutputStream out = null;
        try{
            //--------------------------------------------------
            // 创建流
            out = new FileOutputStream("hell.txt",true);// ***
            // 准备一个字符串
            String str = "吃鸡全靠苟";
            // 将字符串转换为字节数组
            byte[] bytes = str.getBytes();//???

            // 循环的将字节数组的内容写入文件
            for(byte b : bytes) {
                out.write(b);// ****
            }
            //-------------------------------------------------
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try{
                if(out!=null){
                    out.close();
                }
            }catch (IOException ex){
                ex.printStackTrace();
            }
        }
    }
}

写出一个字节数组:

public class FileOutputStreamTest2 {
    public static void main(String[] args) {
        // 申明字节输出流
        OutputStream out = null;
        try{
            //------------------------
            // 创建流
            // 根据文件创建输出流
            File file = new File("st1.txt");
            // 从文件开头开始写数据。 覆盖了原有的数据
            out = new FileOutputStream(file);
            // 准备一个字符串
            String str = "吃鸡全靠苟";
            // 将字符串转换为字节数组
            byte[] bytes = str.getBytes();
            // 直接写出一个字节数组
            out.write(bytes);
            //------------------
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try{
                if(out!=null){
                    out.close();
                }
            }catch (IOException ex){
                ex.printStackTrace();
            }
        }
    }
}

写出字节数组的一部分:

undefined

一个需求:

从控制台输入一个商品的信息,将商品信息写入商品文件。文件中一行存储一个商品信息。​

undefined

再来一个需求:

将上一个需求写文件的商品,读取出来,使用[9527,尤克里里,1525] 形式输出到控制台。​

undefined

文件拷贝:

文件拷贝流程:

java高级-续1

我们来拷贝一个压缩文件:

undefined

字符流

字符流,就是按照字符处理文件的。

字节流,按照字节处理文件。可以处理所有的文件。一般使用中,字节流偏多。

文本文件:纯文本文件。不保存任何的格式,文件头之类的信息。

字符流往往是用来 处理纯文本文件或者网络上的文本信息

字符输入流Reader

Reader本身是一个抽象类

API:

  • abstract void close() 关闭流并释放与之相关联的任何系统资源。
  • void mark(int readAheadLimit) 标记流中的当前位置。
  • boolean markSupported() 告诉这个流是否支持mark()操作。
  • int read() 读一个字符
  • int read(char[] cbuf) 将字符读入数组。
  • abstract int read(char[] cbuf, int off, int len) 将字符读入数组的一部分。
  • int read(CharBuffer target) 尝试将字符读入指定的字符缓冲区。
  • boolean ready() 告诉这个流是否准备好被读取。
  • void reset() 重置流。
  • long skip(long n) 跳过字符

FileReader –Reader类的子类

也是我们常用的字符输入流. (FileInputStream)

构造方法

  • FileReader(File file) 创建一个新的 FileReader ,给出 File读取。
  • FileReader(String fileName) 创建一个新的 FileReader ,给定要读取的文件的名称。

API:所有的API都是来自于父类。

使用:

undefined

字符输出流Writer

API:

  • Writer append (char c) 将指定的字符附加到此作者。
  • Writer append(CharSequence csq) 将指定的字符序列附加到此作者。
  • Writer append(CharSequence csq, int start, int end) 将指定字符序列的子序列附加到此作者。
  • abstract void close() 关闭流,先刷新。
  • abstract void flush() 刷新流。
  • void write(char[] cbuf) 写入一个字符数组。
  • abstract void write(char[] cbuf, int off, int len) 写入字符数组的一部分。
  • void write(int c) 写一个字符
  • void write(String str) 写一个字符串
  • void write(String str, int off, int len) 写一个字符串的一部分。

FileWriter–在字节流中对应:FileOutputStream

构造方法:

  • FileWriter(File file) 给一个File对象构造一个FileWriter对象。
  • FileWriter(File file, boolean append) 给一个File对象构造一个FileWriter对象。
  • FileWriter(String fileName) 构造一个给定文件名的FileWriter对象。
  • FileWriter(String fileName, boolean append) 构造一个FileWriter对象,给出一个带有布尔值的文件名,表示是否附加写入的数据。

没有自己的特殊API。全部是父类的API。

案例:

undefined

下载一个HTML文件

package com.qidian.spider; ​ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; ​

字符流的文件拷贝

package com.qidian.demo1; ​ import java.io.*;

缓冲字符输入流:BufferedReader

构造方法:

  • BufferedReader(Reader in) 创建使用默认大小的输入缓冲区的缓冲字符输入流。
  • BufferedReader(Reader in, int sz) 创建使用指定大小的输入缓冲区的缓冲字符输入流。

在缓冲流中用到了” 装饰设计模式“。 使用BufferedReader包裹一个Reader,实现缓冲。

其中大部分API和Reader没啥区别。有一个特殊的API:

  • *String readLine() 读一行文字。

案例:

undefined

缓冲字符输出流–BufferedWriter

构造方法:

  • BufferedWriter(Writer out) 创建使用默认大小的输出缓冲区的缓冲字符输出流。
  • BufferedWriter(Writer out, int sz) 创建一个新的缓冲字符输出流,使用给定大小的输出缓冲区。

创建BufferedWriter的时候需要包裹一个Writer对象

特殊的API:

  • *void newLine() 写一行行分隔符。

缓冲输出流要注意的问题:

当调用了缓冲输出流的write方法之后,数据可能只是写在缓冲区,并没有实际写到输出流。理论上当关闭输出流的时候,所有缓冲区的数据会刷出。 一般建议我们手动调用 flush方法刷出缓冲区数据。

案例:

undefined

缓冲字节输入流–BufferedInputStream

构造方法

  • BufferedInputStream(InputStream in) 创建一个 BufferedInputStream并保存其参数,输入流 in ,供以后使用。
  • BufferedInputStream(InputStream in, int size) 创建 BufferedInputStream具有指定缓冲区大小,并保存其参数,输入流 in ,供以后使用。

其他的API,不需要说明,和FileOutputStream用法完全一致。只不过提高了底层的效率。

缓冲字节输出流:BufferedOutputStream

构造方法

  • BufferedOutputStream(OutputStream out) 创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
  • BufferedOutputStream(OutputStream out, int size) 创建一个新的缓冲输出流,以便以指定的缓冲区大小将数据写入指定的底层输出流。

API……..你就把它当FileOutputStream使用就行了。

我们使用 缓冲(高效)字节流完成一个文件拷贝的过程。

案例:

undefined

转换流目的:将字节流转换为字符流。 能不能将字符流转换为字节流?NO

转换输入流:InputStreamReader

构造方法:

  • InputStreamReader(InputStream in) 创建一个使用默认字符集的InputStreamReader。
  • InputStreamReader(InputStream in, Charset cs) 创建一个使用给定字符集的InputStreamReader。
  • InputStreamReader(InputStream in, CharsetDecoder dec) 创建一个使用给定字符集解码器的InputStreamReader。
  • InputStreamReader(InputStream in, String charsetName) 创建一个使用命名字符集的InputStreamReader。

API和Reader一致。

转换输出流:OutputStreamWriter

  • OutputStreamWriter(OutputStream out) 创建一个使用默认字符编码的OutputStreamWriter。
  • OutputStreamWriter(OutputStream out, Charset cs) 创建一个使用给定字符集的OutputStreamWriter。
  • OutputStreamWriter(OutputStream out, CharsetEncoder enc) 创建一个使用给定字符集编码器的OutputStreamWriter。
  • OutputStreamWriter(OutputStream out, String charsetName) 创建一个使用命名字符集的OutputStreamWriter。

API和writer完全一致。

案例: 转换输入流。

undefined

字节输出流转换为字符输出流:

案例:

public class OutputStreamWriterTest {
    public static void main(String[] args) {
        OutputStream out = null;
        OutputStreamWriter writer = null;
        try {
            // 创建字节流
            out = new FileOutputStream("hehe.txt");
            // 将字节流包裹成字符流
            writer = new OutputStreamWriter(out);
            // 写字符串
            writer.write("一个字符串\n");
            writer.write("下午两点上课\n");
            writer.write("上完可,做好防护,去做核算");
            writer.flush();
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try{
                if(out!=null){
                    out.close();
                }
            }catch (IOException ex){
                ex.printStackTrace();
            }

        }
    }
}

对象流

序列化

为了方便数据的存储或者传输,将数据或者对象转换为可存储或者传输的形式的过程称之为序列化。相反就是反序列化。

例子:在线购物,卖家给你打包的过程就是序列化。你拆包裹的过程就是反序列化。

项目中的:

将一个对象转换为json输出到客户端。将对象转换为json就是序列化。

将JSON转换对象的过程就是反序列化。

对象流就是专门用来对对象进行序列化和反序列化。

对象输出流:ObjectOutputStream(写出)

专门用来序列化对象的。(卖家打包)

构造方法:

  • ObjectOutputStream(OutputStream out) 创建一个写入指定的OutputStream的ObjectOutputStream。

对象输出流内部其实是包裹了一个字节输出流。

对象输出流的作用:

java高级-续1

API:

  • void close() 关闭流。
  • void write(byte[] buf) 写入一个字节数组。
  • void write(byte[] buf, int off, int len) 写入一个子字节数组。
  • void write(int val) 写一个字节。
  • void writeBoolean(boolean val) 写一个布尔值。
  • void writeByte(int val) 写入一个8位字节。
  • void writeBytes(String str) 写一个字符串作为字节序列。
  • void writeChar(int val) 写一个16位的字符。
  • void writeChars(String str) 写一个字符串作为一系列的字符。
  • void writeDouble(double val) 写一个64位的双倍。
  • void writeFloat(float val) 写一个32位浮点数。
  • void writeInt(int val) 写一个32位int。
  • void writeLong(long val) 写一个64位长
  • void writeShort(int val) 写一个16位短。
  • void writeObject(Object obj) 将指定的对象写入ObjectOutputStream。

对象输出流是写一个对象出去的操作。

java中都有哪些对象?

java中的对象真的很多,但是 所有的对象统称为Object。其实对象流特意准备了几个方法,写这些对象。

  • writeXxxx(Xxx xxx) 这里的Xxxx表示任何一个基本类型。
  • writeObject(Object obj) 其余的类型全部使用Object。

案例1: 序列化基本类型

public class ObjectWriteTest1 {
    public static void main(String[] args) {
        OutputStream out = null;
        ObjectOutputStream objOut = null;
        try{
            // 创建字节输出流
            out = new FileOutputStream("ints.txt");
            // 创建对象流
            objOut = new ObjectOutputStream(out);
            // 写出一个整形
            objOut.writeInt(12);
            objOut.writeDouble(12.5);
            // 刷出数据
            objOut.flush();
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try{
                if(out!=null)
                    out.close();
            }catch (IOException ex){
                ex.printStackTrace();;
            }
        }
    }
}

案例2: 序列化自定义类型

准备一个实体类:

public class User {
    private int id;
    private String name;

}

测试:

java高级-续1

出现异常。

这个异常产生的原因是因为ObjectOutputStream 写的对象 必须实现接口java.io.Serializable。否则无法序列化。这个接口本身是没有任何的方法和成员的,它就是用来标记一个类的对象是否可以被序列化。

public interface Serializable {
}

我们让我们的User类实现这个接口:

java高级-续1

完整的测试代码:

public class ObjectWriteTest2 {
    public static void main(String[] args) {
        OutputStream out = null;
        ObjectOutputStream objOut = null;
        try{
            // 创建字节输出流
            out = new FileOutputStream("u.txt");
            // 创建对象流
            objOut = new ObjectOutputStream(out);
            // 创建一个User
            User u = new User(1,"就乌尔奇");
            // 写出对象u
            objOut.writeObject(u);
            // 刷出数据
            objOut.flush();
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try{
                if(out!=null)
                    out.close();
            }catch (IOException ex){
                ex.printStackTrace();;
            }
        }
    }
}

对象输入流:ObjectInputStream(读取)

专门用来反序列化对象的。(买家拆包裹)

构造方法:

  • ObjectInputStream(InputStream in) 创建从指定的InputStream读取的ObjectInputStream。

ObjectInputStream会包裹一个InputStream

其他的API:

  • int read() 读取一个字节的数据。
  • int read(byte[] buf, int off, int len) 读入一个字节数组。
  • boolean readBoolean() 读取布尔值。
  • byte readByte() 读取一个8位字节。
  • char readChar() 读一个16位字符。
  • double readDouble() 读64位双倍。
  • float readFloat() 读32位浮点数。
  • int readInt() 读取一个32位int。
  • long readLong() 读64位长。
  • short readShort() 读取16位短。
  • Object readObject() 从ObjectInputStream读取一个对象。

有个小问题:无法判定是否到达了文件的末尾。

当使用ObjectInputStream读取数据的时候,如果出现了EOFException。说明到达了文件的末尾。

java高级-续1

案例1: 读取上一小节写入文件的int和double。

public class ObjectInputTest1 {
    public static void main(String[] args) {
        InputStream in = null;
        ObjectInputStream objIn = null;
        try{
            // 创建字节流
            in = new FileInputStream("ints.txt");
            // 创建对象流
            objIn = new ObjectInputStream(in);
            // 反序列化数据
            int i = objIn.readInt();
            System.out.println(i);
            double d = objIn.readDouble();
            System.out.println(d);
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try{
                if(objIn!=null)
                    objIn.close();
            }catch (IOException ex){
                ex.printStackTrace();
            }
        }
    }
}

案例2:读取写入的自定义对象

public class ObjectInputTest2 {
    public static void main(String[] args) {
        InputStream in = null;
        ObjectInputStream objIn = null;
        try{
            // 创建字节流
            in = new FileInputStream("u.txt");
            // 创建对象流
            objIn = new ObjectInputStream(in);
            // 反序列化数据
            Object o = objIn.readObject();
            // 类型转换
            User u = (User) o;
            System.out.println(u);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try{
                if(objIn!=null)
                    objIn.close();
            }catch (IOException ex){
                ex.printStackTrace();;
            }
        }
    }
}

一组对象的读写

情况1: 循环读写

循环的写入数据

public class ObjectWriteTest3 {
    public static void main(String[] args) {
        OutputStream out = null;
        ObjectOutputStream objOut = null;
        try{
            // 创建字节输出流
            out = new FileOutputStream("us.txt");
            // 创建对象流
            objOut = new ObjectOutputStream(out);
            // 创建一组User
            List us = new ArrayList<>();
            for (int i = 0;i< 100; i++){
                us.add(new User(i+1,"鸣人"+i));
            }
            // 循环的写出对象
            for (User u : us) {
                objOut.writeObject(u);
            }
            // 刷出数据
            objOut.flush();
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try{
                if(out!=null)
                    out.close();
            }catch (IOException ex){
                ex.printStackTrace();;
            }
        }
    }
}

循环的读数据

public class ObjectInputTest3 {
    public static void main(String[] args) {
        InputStream in = null;
        ObjectInputStream objIn = null;
        try{
            // 创建字节流
            in = new FileInputStream("us.txt");
            // 创建对象流
            objIn = new ObjectInputStream(in);
            // 反序列化数据
            // 循环读取数据
            // 知道循环次数的处理
//            for (int i = 0;i < 100;i++){
//                Object o = objIn.readObject();
//                User u = (User) o;
//                System.out.println(u);
//            }
            // 不知道循环次数
            while(true){
                // 当到达文件的末尾的时候,会抛出异常EOFException
                Object o = objIn.readObject();
                User u = (User) o;
                System.out.println(u);
            }
        }catch(EOFException e){
            System.out.println("读取完成");
        } catch (Exception e){
            e.printStackTrace();
        }finally {
            try{
                if(objIn!=null)
                    objIn.close();
            }catch (IOException ex){
                ex.printStackTrace();;
            }
        }
    }
}

Original: https://www.cnblogs.com/xiaoxiaodeboke/p/16032817.html
Author: 潇潇消消气
Title: java高级-续1

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/581269/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 2、spring+mybatis注解(无mapper实现类)+idea+maven

    1、在idea中配置database 连接数据库,用来在idea中编写sql脚本操作数据库 2、sql详细脚本如下: 1 –1.创建部门表 2 create table dept…

    Java 2023年6月13日
    062
  • 识别vite别名路径方法

    1、vite.config.js 修改 在 vie.config.js一级目录下添加一下配置 resolve: { // alias: [{ find: /^~/, replace…

    Java 2023年6月8日
    085
  • java面试——反射与泛型

    《java核心技术》 官方套话:能够分析类能力的程序成为反射。 又通过网上搜索有这句话: 反射指程序可以访问、检测和修改它本身状态或行为的一种能力。 “明明我自己能直接…

    Java 2023年6月9日
    084
  • 虚拟机栈的五道面试题

    虚拟机栈的五道面试题 1、举例栈溢出的情况?(StackOverFlowError) 通过-Xss设置栈的大小如果采用固定大小的java虚拟机栈,每一个线程的java虚拟机栈容量在…

    Java 2023年6月14日
    073
  • mybatis学习笔记(二)for 实践

    mybatis基本应用 1 快速入门 myBatis官网地址:http://www.mybatis.org/mybatis-3/ 1.1 开发步骤 引入依赖 创建user表 编写U…

    Java 2023年6月5日
    092
  • windows系统python3.6(Anaconda3)安装对应版本 torch、torchvision

    一、官网下载 .whl 文件 https://download.pytorch.org/whl/torch_stable.html 二、使用pip命令安装 打开你的anaconda…

    Java 2023年6月15日
    077
  • C语言-字符串函数的实现(三)之strcat

    C语言中的字符串函数有如下这些 获取字符串长度 strlen 长度不受限制的字符串函数 strcpy strcat strcmp 长度受限制的字符串函数 strncpy strnc…

    Java 2023年6月10日
    077
  • 通过刷题HTML遇到的问题

    通过刷题HTML遇到的问题 1、有关选择器的权重问题 1.通配符选择器和继承:权重为0,2.标签选择器:权重为00013.类选择器:权重为00104.id选择器:权重为01005….

    Java 2023年6月14日
    084
  • 好玩Python——PIL项目实训(二)

    1 # -*- coding: utf-8 -*- 2 """ 3 Created on Sun Apr 12 22:03:26 2020 4 5 @…

    Java 2023年6月6日
    0105
  • .NET 7 RC1 正式发布

    可以通过个网站( )跟踪.NET 7的issue 情况,今天截止还有36项在接下来的2个月时间内消灭。 下面是最新的燃尽图: 微软的公告主要回顾了与.NET MAUI、云原生最佳实…

    Java 2023年6月5日
    074
  • 四、初识Java

    JavaSE:标准版(桌面程序,控制台开发……) JavaME:嵌入式开发(手机,小家电……)[了解就行] JavaEE:E企业级开…

    Java 2023年6月5日
    077
  • 数学分析笔记汇总

    数学分析笔记汇总 笔记的名字虽然说是”数学分析”,但是还是高等数学的内容为主。至于为什么不叫”高等数学”笔记,是因为”高…

    Java 2023年6月7日
    073
  • nacos 快速入门

    外表可是具有欺骗性的。 No victory comes without a price. 凡是成功就要付出代价。 这个快速开始手册是帮忙您快速在您的电脑上,下载、安装并使用 na…

    Java 2023年6月9日
    0133
  • Spring StateMachine状态机

    一、状态机 有限状态机是一种用来进行对象行为建模的工具,其作用主要是描述对象在它的生命周期内所经历的状态序列,以及如何响应来自外界的各种事件。在电商场景(订单、物流、售后)、社交(…

    Java 2023年5月30日
    077
  • jsoup教程

    在爬虫的时候,当我们用HttpClient之类的框架,获取到网页源码之后,需要从网页源码中取出我们想要的内容, 就可以使用jsoup这类HTML解析器了。可以非常轻松的实现。 虽然…

    Java 2023年6月7日
    077
  • java监控文件变化,并分别使用RandomAccessFile和BufferedReader读取

    import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import j…

    Java 2023年5月29日
    0101
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球