file类与IO流
发布时间:2026/11/5 10:00:30 锦皓数字建站

file类与IO流java.io.File类File类及本章下的各种流都定义在java.io包下。一个File对象代表硬盘或网络中可能存在的一个文件或者文件目录俗称文件夹与平台无关。体会万事万物皆对象File 能新建、删除、重命名文件和目录但 File 不能访问文件内容本身。如果需要访问文件内容本身则需要使用输入/输出流。File对象可以作为参数传递给流的构造器。想要在Java程序中表示一个真实存在的文件或目录那么必须有一个File对象但是Java程序中的一个File对象可能没有一个真实存在的文件或目录public File(String pathname)以pathname为路径创建File对象可以是绝对路径或者相对路径如果pathname是相对路径则默认的当前路径在系统属性user.dir中存储。*public File(String parent, String child)以parent为父路径child为子路径创建File对象。*public File(File parent, String child)根据一个父File对象和子文件路径创建File对象关于路径绝对路径从盘符开始的路径这是一个完整的路径。相对路径相对于项目目录的路径这是一个便捷的路径开发中经常使用。IDEA中main中的文件的相对路径是相对于当前工程IDEA中单元测试方法中的文件的相对路径是相对于当前module注意无论该路径下是否存在文件或者目录都不影响File对象的创建。window的路径分隔符使用“\”而Java程序中的“\”表示转义字符所以在Windows中表示路径需要用“\”。或者直接使用“/”也可以Java程序支持将“/”当成平台无关的路径分隔符。或者直接使用File.separator常量值表示。比如File file2 new File(d: File.separator atguigu File.separator info.txt);当构造路径是绝对路径时那么getPath和getAbsolutePath结果一样当构造路径是相对路径时那么getAbsolutePath的路径 user.dir的路径 构造路径常用方法1、获取文件和目录基本信息public String getName() 获取名称public String getPath() 获取路径public String getAbsolutePath()获取绝对路径public File getAbsoluteFile()获取绝对路径表示的文件public String getParent()获取上层文件目录路径。若无返回nullpublic long length() 获取文件长度即字节数。不能获取目录的长度。public long lastModified() 获取最后一次的修改时间毫秒值如果File对象代表的文件或目录存在则File对象实例初始化时就会用硬盘中对应文件或目录的属性信息例如时间、类型等为File对象的属性赋值否则除了路径和名称File对象的其他属性将会保留默认值。列出目录的下一级public String[] list() 返回一个String数组表示该File目录中的所有子文件或目录。public File[] listFiles() 返回一个File数组表示该File目录中的所有的子文件或目录。File类的重命名功能public boolean renameTo(File dest):把文件重命名为指定的文件路径。判断功能的方法public boolean exists()此File表示的文件或目录是否实际存在。public boolean isDirectory()此File表示的是否为目录。public boolean isFile()此File表示的是否为文件。public boolean canRead() 判断是否可读public boolean canWrite() 判断是否可写public boolean isHidden() 判断是否隐藏创建、删除功能public boolean createNewFile()创建文件。若文件存在则不创建返回false。public boolean mkdir()创建文件目录。如果此文件目录存在就不创建了。如果此文件目录的上层目录不存在也不创建。public boolean mkdirs()创建文件目录。如果上层文件目录不存在一并创建。public boolean delete()删除文件或者文件夹删除注意事项① Java中的删除不走回收站。② 要删除一个文件目录请注意该文件目录内不能包含文件或者文件目录。API中说明delete方法如果此File表示目录则目录必须为空才能删除。Java IO原理Java程序中对于数据的输入/输出操作以“流(stream)” 的方式进行可以看做是一种数据的流动。- I/O流中的I/O是Input/Output的缩写 I/O技术是非常实用的技术用于处理设备之间的数据传输。如读/写文件网络通讯等。-输入input读取外部数据磁盘、光盘等存储设备的数据到程序内存中。-输出output将程序内存数据输出到磁盘、光盘等存储设备中。流的分类java.io包下提供了各种“流”类和接口用以获取不同种类的数据并通过标准的方法输入或输出数据。按数据的流向不同分为输入流和输出流。输入流把数据从其他设备上读取到内存中的流。以InputStream、Reader结尾输出流把数据从内存中写出到其他设备上的流。以OutputStream、Writer结尾按操作数据单位的不同分为字节流8bit和字符流16bit。字节流以字节为单位读写数据的流。以InputStream、OutputStream结尾字符流以字符为单位读写数据的流。以Reader、Writer结尾根据IO流的角色不同分为节点流和处理流。节点流直接从数据源或目的地读写数据处理流不直接连接到数据源或目的地而是“连接”在已存在的流节点流或处理流之上通过对数据的处理为程序提供更为强大的读写功能。流的APIJava的IO流共涉及40多个类实际上非常规则都是从如下4个抽象基类派生的。抽象基类输入流输出流字节流InputStreamOutputStream字符流ReaderWriter由这四个类派生出来的子类名称都是以其父类名作为子类名后缀。常用的节点流文件流 FileInputStream、FileOutputStrean、FileReader、FileWriter字节/字符数组流 ByteArrayInputStream、ByteArrayOutputStream、CharArrayReader、CharArrayWriter对数组进行处理的节点流对应的不再是文件而是内存中的一个数组。常用处理流缓冲流BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter作用增加缓冲功能避免频繁读写硬盘进而提升读写效率。转换流InputStreamReader、OutputStreamReader作用实现字节流和字符流之间的转换。对象流ObjectInputStream、ObjectOutputStream作用提供直接读写Java对象功能节点流之一FileReader\FileWriterReader与WriterJava提供一些字符流类以字符为单位读写数据专门用于处理文本文件。不能操作图片视频等非文本文件。常见的文本文件有如下的格式.txt、.java、.c、.cpp、.py等注意.doc、.xls、.ppt这些都不是文本文件。字符输入流Readerjava.io.Reader抽象类是表示用于读取字符流的所有类的父类可以读取字符信息到内存中。它定义了字符输入流的基本共性功能方法。public int read() 从输入流读取一个字符。 虽然读取了一个字符但是会自动提升为int类型。返回该字符的Unicode编码值。如果已经到达流末尾了则返回-1。public int read(char[] cbuf) 从输入流中读取一些字符并将它们存储到字符数组 cbuf中 。每次最多读取cbuf.length个字符。返回实际读取的字符个数。如果已经到达流末尾没有数据可读则返回-1。public int read(char[] cbuf,int off,int len)从输入流中读取一些字符并将它们存储到字符数组 cbuf中从cbuf[off]开始的位置存储。每次最多读取len个字符。返回实际读取的字符个数。如果已经到达流末尾没有数据可读则返回-1。public void close()关闭此流并释放与此流相关联的任何系统资源。注意当完成流的操作时必须调用close()方法释放系统资源否则会造成内存泄漏。字符输出流Writerjava.io.Writer抽象类是表示用于写出字符流的所有类的超类将指定的字符信息写出到目的地。它定义了字节输出流的基本共性功能方法。public void write(int c)写出单个字符。public void write(char[] cbuf)写出字符数组。public void write(char[] cbuf, int off, int len)写出字符数组的某一部分。off数组的开始索引len写出的字符个数。public void write(String str)写出字符串。public void write(String str, int off, int len)写出字符串的某一部分。off字符串的开始索引len写出的字符个数。public void flush()刷新该流的缓冲。public void close()关闭此流。注意当完成流的操作时必须调用close()方法释放系统资源否则会造成内存泄漏。FileReaderjava.io.FileReader类用于读取字符文件构造时使用系统默认的字符编码和默认字节缓冲区。FileReader(File file) 创建一个新的 FileReader 给定要读取的File对象。FileReader(String fileName) 创建一个新的 FileReader 给定要读取的文件的名称。FileWriterjava.io.FileWriter类用于写出字符到文件构造时使用系统默认的字符编码和默认字节缓冲区。FileWriter(File file) 创建一个新的 FileWriter给定要读取的File对象。FileWriter(String fileName) 创建一个新的 FileWriter给定要读取的文件的名称。FileWriter(File file,boolean append) 创建一个新的 FileWriter指明是否在现有文件末尾追加内容。小结① 因为出现流资源的调用为了避免内存泄漏需要使用try-catch-finally处理异常 ② 对于输入流来说File类的对象必须在物理磁盘上存在否则执行就会报FileNotFoundException。如果传入的是一个目录则会报IOException异常。 对于输出流来说File类的对象是可以不存在的。 如果File类的对象不存在则可以在输出的过程中自动创建File类的对象 如果File类的对象存在 如果调用FileWriter(File file)或FileWriter(File file,false)输出时会新建File文件覆盖已有的文件 如果调用FileWriter(File file,true)构造器则在现有的文件末尾追加写出内容。关于flush刷新因为内置缓冲区的原因如果FileWriter不关闭输出流无法写出字符到文件中。但是关闭的流对象是无法继续写出数据的。如果我们既想写出数据又想继续使用流就需要flush()方法了。flush()刷新缓冲区流对象可以继续使用。close()先刷新缓冲区然后通知系统释放资源。流对象不可以再被使用了。注意即便是flush()方法写出了数据操作的最后还是要调用close方法释放系统资源。节点流之二FileInputStream\FileOutputStream如果我们读取或写出的数据是非文本文件则Reader、Writer就无能为力了必须使用字节流。InputStream和OutputStream字节输入流InputStreamjava.io.InputStream抽象类是表示字节输入流的所有类的超类可以读取字节信息到内存中。它定义了字节输入流的基本共性功能方法。public int read() 从输入流读取一个字节。返回读取的字节值。虽然读取了一个字节但是会自动提升为int类型。如果已经到达流末尾没有数据可读则返回-1。public int read(byte[] b) 从输入流中读取一些字节数并将它们存储到字节数组 b中 。每次最多读取b.length个字节。返回实际读取的字节个数。如果已经到达流末尾没有数据可读则返回-1。public int read(byte[] b,int off,int len)从输入流中读取一些字节数并将它们存储到字节数组 b中从b[off]开始存储每次最多读取len个字节 。返回实际读取的字节个数。如果已经到达流末尾没有数据可读则返回-1。public void close()关闭此输入流并释放与此流相关联的任何系统资源。说明close()方法当完成流的操作时必须调用此方法释放系统资源。字节输出流OutputStreamjava.io.OutputStream抽象类是表示字节输出流的所有类的超类将指定的字节信息写出到目的地。它定义了字节输出流的基本共性功能方法。public void write(int b)将指定的字节输出流。虽然参数为int类型四个字节但是只会保留一个字节的信息写出。public void write(byte[] b)将 b.length字节从指定的字节数组写入此输出流。public void write(byte[] b, int off, int len)从指定的字节数组写入 len字节从偏移量 off开始输出到此输出流。public void flush()刷新此输出流并强制任何缓冲的输出字节被写出。public void close()关闭此输出流并释放与此流相关联的任何系统资源。说明close()方法当完成流的操作时必须调用此方法释放系统资源。FileInputStream 与 FileOutputStreamFileInputStreamjava.io.FileInputStream类是文件输入流从文件中读取字节。FileInputStream(File file) 通过打开与实际文件的连接来创建一个 FileInputStream 该文件由文件系统中的 File对象 file命名。FileInputStream(String name) 通过打开与实际文件的连接来创建一个 FileInputStream 该文件由文件系统中的路径名 name命名。FileOutputStreamjava.io.FileOutputStream类是文件输出流用于将数据写出到文件。public FileOutputStream(File file)创建文件输出流写出由指定的 File对象表示的文件。public FileOutputStream(String name) 创建文件输出流指定的名称为写出文件。public FileOutputStream(File file, boolean append) 创建文件输出流指明是否在现有文件末尾追加内容。处理流之一缓冲流为了提高数据读写的速度Java API提供了带缓冲功能的流类缓冲流。缓冲流要“套接”在相应的节点流之上根据数据操作单位可以把缓冲流分为字节缓冲流BufferedInputStreamBufferedOutputStream字符缓冲流BufferedReaderBufferedWriter缓冲流的基本原理在创建流对象时内部会创建一个缓冲区数组缺省使用8192个字节(8Kb)的缓冲区通过缓冲区读写减少系统IO次数从而提高读写的效率。构造器public BufferedInputStream(InputStream in)创建一个 新的字节型的缓冲输入流。public BufferedOutputStream(OutputStream out) 创建一个新的字节型的缓冲输出流。public BufferedReader(Reader in)创建一个 新的字符型的缓冲输入流。public BufferedWriter(Writer out) 创建一个新的字符型的缓冲输出流。字符缓冲流特有方法字符缓冲流的基本方法与普通字符流调用方式一致不再阐述我们来看它们具备的特有方法。BufferedReaderpublic String readLine(): 读一行文字。BufferedWriterpublic void newLine(): 写一行行分隔符,由系统属性定义符号。说明涉及到嵌套的多个流时如果都显式关闭的话需要先关闭外层的流再关闭内层的流其实在开发中只需要关闭最外层的流即可因为在关闭外层流时内层的流也会被关闭。处理流之二转换流问题引入引入情况1使用FileReader读取项目中的文本文件。由于IDEA设置中针对项目设置了UTF-8编码当读取Windows系统中创建的文本文件时如果Windows系统默认的是GBK编码则读入内存中会出现乱码。那么如何读取GBK编码的文件呢引入情况2针对文本文件现在使用一个字节流进行数据的读入希望将数据显示在控制台上。此时针对包含中文的文本数据可能会出现乱码。转换流的理解作用转换流是字节与字符间的桥梁InputStreamReader 与 OutputStreamWriterInputStreamReader转换流java.io.InputStreamReader是Reader的子类是从字节流到字符流的桥梁。它读取字节并使用指定的字符集将其解码为字符。它的字符集可以由名称指定也可以接受平台的默认字符集。构造器InputStreamReader(InputStream in): 创建一个使用默认字符集的字符流。InputStreamReader(InputStream in, String charsetName): 创建一个指定字符集的字符流。OutputStreamWriter- 转换流java.io.OutputStreamWriter是Writer的子类是从字符流到字节流的桥梁。使用指定的字符集将字符编码为字节。它的字符集可以由名称指定也可以接受平台的默认字符集。构造器OutputStreamWriter(OutputStream in): 创建一个使用默认字符集的字符流。OutputStreamWriter(OutputStream in,String charsetName): 创建一个指定字符集的字符流。字符编码和字符集编码与解码计算机中储存的信息都是用二进制数表示的而我们在屏幕上看到的数字、英文、标点符号、汉字等字符是二进制数转换之后的结果。按照某种规则将字符存储到计算机中称为编码。反之将存储在计算机中的二进制数按照某种规则解析显示出来称为解码。字符编码Character Encoding: 就是一套自然语言的字符与二进制数之间的对应规则。编码表生活中文字和计算机中二进制的对应规则乱码的情况按照A规则存储同样按照A规则解析那么就能显示正确的文本符号。反之按照A规则存储再按照B规则解析就会导致乱码现象。编码:字符(人能看懂的)--字节(人看不懂的) 解码:字节(人看不懂的)--字符(人能看懂的)字符集字符集Charset也叫编码表。是一个系统支持的所有字符的集合包括各国家文字、标点符号、图形符号、数字等。计算机要准确的存储和识别各种字符集符号需要进行字符编码一套字符集必然至少有一套字符编码。常见字符集有ASCII字符集、GBK字符集、Unicode字符集等。可见当指定了编码它所对应的字符集自然就指定了所以编码才是我们最终要关心的。ASCII字符集ASCII码American Standard Code for Information Interchange美国信息交换标准代码上个世纪60年代美国制定了一套字符编码对英语字符与二进制位之间的关系做了统一规定。这被称为ASCII码。ASCII码用于显示现代英语主要包括控制字符回车键、退格、换行键等和可显示字符英文大小写字符、阿拉伯数字和西文符号。基本的ASCII字符集使用7位bits表示一个字符最前面的1位统一规定为0共128个字符。比如空格“SPACE”是32二进制00100000大写的字母A是65二进制01000001。缺点不能表示所有字符。ISO-8859-1字符集拉丁码表别名Latin-1用于显示欧洲使用的语言包括荷兰语、德语、意大利语、葡萄牙语等ISO-8859-1使用单字节编码兼容ASCII编码。GBxxx字符集GB就是国标的意思是为了显示中文而设计的一套字符集。GB2312简体中文码表。一个小于127的字符的意义与原来相同即向下兼容ASCII码。但两个大于127的字符连在一起时就表示一个汉字这样大约可以组合了包含7000多个简体汉字此外数学符号、罗马希腊的字母、日文的假名们都编进去了这就是常说的全角字符而原来在127号以下的那些符号就叫半角字符了。GBK最常用的中文码表。是在GB2312标准基础上的扩展规范使用了双字节编码方案共收录了21003个汉字完全兼容GB2312标准同时支持繁体汉字以及日韩汉字等。GB18030最新的中文码表。收录汉字70244个采用多字节编码每个字可以由1个、2个或4个字节组成。支持中国国内少数民族的文字同时支持繁体汉字以及日韩汉字等。Unicode字符集Unicode编码为表达任意语言的任意字符而设计也称为统一码、标准万国码。Unicode 将世界上所有的文字用2个字节统一进行编码为每个字符设定唯一的二进制编码以满足跨语言、跨平台进行文本处理的要求。Unicode 的缺点这里有三个问题第一英文字母只用一个字节表示就够了如果用更多的字节存储是极大的浪费。第二如何才能区别Unicode和ASCII计算机怎么知道两个字节表示一个符号而不是分别表示两个符号呢第三如果和GBK等双字节编码方式一样用最高位是1或0表示两个字节和一个字节就少了很多值无法用于表示字符不够表示所有字符。Unicode在很长一段时间内无法推广直到互联网的出现为解决Unicode如何在网络上传输的问题于是面向传输的众多 UTFUCS Transfer Format标准出现。具体来说有三种编码方案UTF-8、UTF-16和UTF-32。UTF-8字符集Unicode是字符集UTF-8、UTF-16、UTF-32是三种将数字转换到程序数据的编码方案。顾名思义UTF-8就是每次8个位传输数据而UTF-16就是每次16个位。其中UTF-8 是在互联网上使用最广的一种 Unicode 的实现方式。互联网工程工作小组IETF要求所有互联网协议都必须支持UTF-8编码。所以我们开发Web应用也要使用UTF-8编码。UTF-8 是一种变长的编码方式。它使用1-4个字节为每个字符编码编码规则128个US-ASCII字符只需一个字节编码。拉丁文等字符需要二个字节编码。大部分常用字含中文使用三个字节编码。其他极少使用的Unicode辅助字符使用四字节编码。处理流之三/四数据流、对象流数据流与对象流说明如果需要将内存中定义的变量包括基本数据类型或引用数据类型保存在文件中那怎么办呢int age 300; char gender 男; int energy 5000; double price 75.5; boolean relive true; String name 巫师; Student stu new Student(张三,23,89);Java提供了数据流和对象流来处理这些类型的数据数据流DataOutputStream、DataInputStreamDataOutputStream允许应用程序将基本数据类型、String类型的变量写入输出流中DataInputStream允许应用程序以与机器无关的方式从底层输入流中读取基本数据类型、String类型的变量。数据流DataInputStream中的方法byte readByte() short readShort() int readInt() long readLong() float readFloat() double readDouble() char readChar() boolean readBoolean() String readUTF() void readFully(byte[] b)数据流DataOutputStream中的方法将上述的方法的read改为相应的write即可。数据流的弊端只支持Java基本数据类型和字符串的读写而不支持其它Java对象的类型。而ObjectOutputStream和ObjectInputStream既支持Java基本数据类型的数据读写又支持Java对象的读写所以重点介绍对象流ObjectOutputStream和ObjectInputStream。对象流ObjectOutputStream、ObjectInputStreamObjectOutputStream将 Java 基本数据类型和对象写入字节输出流中。通过在流中使用文件可以实现Java各种基本数据类型的数据以及对象的持久存储。ObjectInputStreamObjectInputStream 对以前使用 ObjectOutputStream 写出的基本数据类型的数据和对象进行读入操作保存在内存中。说明对象流的强大之处就是可以把Java中的对象写入到数据源中也能把对象从数据源中还原回来。对象流APIObjectOutputStream中的构造器public ObjectOutputStream(OutputStream out) 创建一个指定的ObjectOutputStream。FileOutputStream fos new FileOutputStream(game.dat); ObjectOutputStream oos new ObjectOutputStream(fos);ObjectOutputStream中的方法public void writeBoolean(boolean val)写出一个 boolean 值。public void writeByte(int val)写出一个8位字节public void writeShort(int val)写出一个16位的 short 值public void writeChar(int val)写出一个16位的 char 值public void writeInt(int val)写出一个32位的 int 值public void writeLong(long val)写出一个64位的 long 值public void writeFloat(float val)写出一个32位的 float 值。public void writeDouble(double val)写出一个64位的 double 值public void writeUTF(String str)将表示长度信息的两个字节写入输出流后跟字符串 s 中每个字符的 UTF-8 修改版表示形式。根据字符的值将字符串 s 中每个字符转换成一个字节、两个字节或三个字节的字节组。注意将 String 作为基本数据写入流中与将它作为 Object 写入流中明显不同。 如果 s 为 null则抛出 NullPointerException。public void writeObject(Object obj)写出一个obj对象public void close() 关闭此输出流并释放与此流相关联的任何系统资源ObjectInputStream中的构造器public ObjectInputStream(InputStream in) 创建一个指定的ObjectInputStream。FileInputStream fis new FileInputStream(game.dat); ObjectInputStream ois new ObjectInputStream(fis);ObjectInputStream中的方法public boolean readBoolean()读取一个 boolean 值public byte readByte()读取一个 8 位的字节public short readShort()读取一个 16 位的 short 值public char readChar()读取一个 16 位的 char 值public int readInt()读取一个 32 位的 int 值public long readLong()读取一个 64 位的 long 值public float readFloat()读取一个 32 位的 float 值public double readDouble()读取一个 64 位的 double 值public String readUTF()读取 UTF-8 修改版格式的 Stringpublic void readObject(Object obj)读入一个obj对象public void close() 关闭此输入流并释放与此流相关联的任何系统资源认识对象序列化机制1、何为对象序列化机制对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流从而允许把这种二进制流持久地保存在磁盘上或通过网络将这种二进制流传输到另一个网络节点。//当其它程序获取了这种二进制流就可以恢复成原来的Java对象。序列化过程用一个字节序列可以表示一个对象该字节序列包含该对象的类型和对象中存储的属性等信息。字节序列写出到文件之后相当于文件中持久保存了一个对象的信息。反序列化过程该字节序列还可以从文件中读取回来重构对象对它进行反序列化。对象的数据、对象的类型和对象中存储的数据信息都可以用来在内存中创建对象。2、序列化机制的重要性序列化是 RMIRemote Method Invoke、远程方法调用过程的参数和返回值都必须实现的机制而 RMI 是 JavaEE 的基础。因此序列化机制是 JavaEE 平台的基础。序列化的好处在于可将任何实现了Serializable接口的对象转化为字节数据使其在保存和传输时可被还原。3、实现原理序列化用ObjectOutputStream类保存基本类型数据或对象的机制。方法为public final void writeObject (Object obj): 将指定的对象写出。反序列化用ObjectInputStream类读取基本类型数据或对象的机制。方法为public final Object readObject (): 读取一个对象。如何实现序列化机制如果需要让某个对象支持序列化机制则必须让对象所属的类及其属性是可序列化的为了让某个类是可序列化的该类必须实现java.io.Serializable接口。Serializable是一个标记接口不实现此接口的类将不会使任何状态序列化或反序列化会抛出NotSerializableException。如果对象的某个属性也是引用数据类型那么如果该属性也要序列化的话也要实现Serializable接口该类的所有属性必须是可序列化的。如果有一个属性不需要可序列化的则该属性必须注明是瞬态的使用transient关键字修饰。静态static变量的值不会序列化。因为静态变量的值不属于某个对象。反序列化失败问题问题1对于JVM可以反序列化对象它必须是能够找到class文件的类。如果找不到该类的class文件则抛出一个ClassNotFoundException异常。问题2当JVM反序列化对象时能找到class文件但是class文件在序列化对象之后发生了修改那么反序列化操作也会失败抛出一个InvalidClassException异常。发生这个异常的原因如下该类的序列版本号与从流中读取的类描述符的版本号不匹配该类包含未知数据类型解决办法Serializable接口给需要序列化的类提供了一个序列版本号serialVersionUID。凡是实现 Serializable接口的类都应该有一个表示序列化版本标识符的静态变量static final long serialVersionUID 234242343243L; //它的值由程序员随意指定即可。serialVersionUID用来表明类的不同版本间的兼容性。简单来说Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较如果相同就认为是一致的可以进行反序列化否则就会出现序列化版本不一致的异常(InvalidCastException)。如果类没有显示定义这个静态常量它的值是Java运行时环境根据类的内部细节自动生成的。若类的实例变量做了修改serialVersionUID可能发生变化。因此建议显式声明。如果声明了serialVersionUID即使在序列化完成之后修改了类导致类重新编译则原来的数据也能正常反序列化只是新增的字段值是默认值而已。package com.atguigu.object; import java.io.Serializable; public class Employee implements Serializable { private static final long serialVersionUID 1324234L; //增加serialVersionUID //其它结构略 }面试题谈谈你对java.io.Serializable接口的理解我们知道它用于序列化是空方法接口还有其它认识吗实现了Serializable接口的对象可将它们转换成一系列字节并可在以后完全恢复回原来的样子。这一过程亦可通过网络进行。这意味着序列化机制能自动补偿操作系统间的差异。换句话说可以先在Windows机器上创建一个对象对其序列化然后通过网络发给一台Unix机器然后在那里准确无误地重新“装配”。不必关心数据在不同机器上如何表示也不必关心字节的顺序或者其他任何细节。 由于大部分作为参数的类如String、Integer等都实现了java.io.Serializable的接口也可以利用多态的性质作为参数使接口更灵活。其他流的使用标准输入、输出流System.in和System.out分别代表了系统标准的输入和输出设备默认输入设备是键盘输出设备是显示器System.in的类型是InputStreamSystem.out的类型是PrintStream其是OutputStream的子类FilterOutputStream 的子类重定向通过System类的setInsetOut方法对默认设备进行改变。public static void setIn(InputStream in)public static void setOut(PrintStream out)展**System类中有三个常量对象System.out、System.in、System.err查看System类中这三个常量对象的声明public final static InputStream in null; public final static PrintStream out null; public final static PrintStream err null;奇怪的是这三个常量对象有final声明但是却初始化为null。final声明的常量一旦赋值就不能修改那么null不会空指针异常吗这三个常量对象为什么要小写final声明的常量按照命名规范不是应该大写吗这三个常量的对象有set方法final声明的常量不是不能修改值吗set方法是如何修改它们的值的final声明的常量表示在Java的语法体系中它们的值是不能修改的而这三个常量对象的值是由C/C等系统函数进行初始化和修改值的所以它们故意没有用大写也有set方法。public static void setOut(PrintStream out) { checkIO(); setOut0(out); } public static void setErr(PrintStream err) { checkIO(); setErr0(err); } public static void setIn(InputStream in) { checkIO(); setIn0(in); } private static void checkIO() { SecurityManager sm getSecurityManager(); if (sm ! null) { sm.checkPermission(new RuntimePermission(setIO)); } } private static native void setIn0(InputStream in); private static native void setOut0(PrintStream out); private static native void setErr0(PrintStream err);打印流实现将基本数据类型的数据格式转化为字符串输出。打印流PrintStream和PrintWriter提供了一系列重载的print()和println()方法用于多种数据类型的输出PrintStream和PrintWriter的输出不会抛出IOException异常PrintStream和PrintWriter有自动flush功能PrintStream 打印的所有字符都使用平台的默认字符编码转换为字节。在需要写入字符而不是写入字节的情况下应该使用 PrintWriter 类。System.out返回的是PrintStream的实例构造器PrintStream(File file) 创建具有指定文件且不带自动行刷新的新打印流。PrintStream(File file, String csn)创建具有指定文件名称和字符集且不带自动行刷新的新打印流。PrintStream(OutputStream out) 创建新的打印流。PrintStream(OutputStream out, boolean autoFlush)创建新的打印流。 autoFlush如果为 true则每当写入 byte 数组、调用其中一个 println 方法或写入换行符或字节 (\n) 时都会刷新输出缓冲区。PrintStream(OutputStream out, boolean autoFlush, String encoding) 创建新的打印流。PrintStream(String fileName)创建具有指定文件名称且不带自动行刷新的新打印流。PrintStream(String fileName, String csn) 创建具有指定文件名称和字符集且不带自动行刷新的新打印流。Scanner类构造方法Scanner(File source) 构造一个新的 Scanner它生成的值是从指定文件扫描的。Scanner(File source, String charsetName) 构造一个新的 Scanner它生成的值是从指定文件扫描的。Scanner(InputStream source) 构造一个新的 Scanner它生成的值是从指定的输入流扫描的。Scanner(InputStream source, String charsetName) 构造一个新的 Scanner它生成的值是从指定的输入流扫描的。常用方法boolean hasNextXxx() 如果通过使用nextXxx()方法此扫描器输入信息中的下一个标记可以解释为默认基数中的一个 Xxx 值则返回 true。Xxx nextXxx() 将输入信息的下一个标记扫描为一个Xxxapache-common包的使用介绍IO技术开发中代码量很大而且代码的重复率较高为此Apache软件基金会开发了IO技术的工具类commonsIO大大简化了IO开发。Apahce软件基金会属于第三方Oracle公司第一方我们自己第二方其他都是第三方我们要使用第三方开发好的工具需要添加jar包。9导包及举例在导入commons-io-2.5.jar包之后内部的API都可以使用。IOUtils类的使用- 静态方法IOUtils.copy(InputStream in,OutputStream out)传递字节流实现文件复制。 - 静态方法IOUtils.closeQuietly(任意流对象)悄悄的释放资源自动处理close()方法抛出的异常。public class Test01 { public static void main(String[] args)throws Exception { //- 静态方法IOUtils.copy(InputStream in,OutputStream out)传递字节流实现文件复制。 IOUtils.copy(new FileInputStream(E:\\Idea\\io\\1.jpg),new FileOutputStream(E:\\Idea\\io\\file\\柳岩.jpg)); //- 静态方法IOUtils.closeQuietly(任意流对象)悄悄的释放资源自动处理close()方法抛出的异常。 /* FileWriter fw null; try { fw new FileWriter(day21\\io\\writer.txt); fw.write(hahah); } catch (IOException e) { e.printStackTrace(); }finally { IOUtils.closeQuietly(fw); }*/ } }FileUtils类的使用- 静态方法void copyDirectoryToDirectory(File src,File dest)整个目录的复制自动进行递归遍历 参数: src:要复制的文件夹路径 dest:要将文件夹粘贴到哪里去 - 静态方法void writeStringToFile(File file,String content)将内容content写入到file中 - 静态方法String readFileToString(File file)读取文件内容并返回一个String - 静态方法void copyFile(File srcFile,File destFile)文件复制public class Test02 { public static void main(String[] args) { try { //- 静态方法void copyDirectoryToDirectory(File src,File dest); FileUtils.copyDirectoryToDirectory(new File(E:\\Idea\\io\\aa),new File(E:\\Idea\\io\\file)); //- 静态方法writeStringToFile(File file,String str) FileUtils.writeStringToFile(new File(day21\\io\\commons.txt),柳岩你好); //- 静态方法String readFileToString(File file) String s FileUtils.readFileToString(new File(day21\\io\\commons.txt)); System.out.println(s); //- 静态方法void copyFile(File srcFile,File destFile) FileUtils.copyFile(new File(io\\yangm.png),new File(io\\yangm2.png)); System.out.println(复制成功); } catch (IOException e) { e.printStackTrace(); } } }
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。