目录
一、file类
1.1 基本概念
- 1. File类的 一个对象,代表一一个文件或一个文件目录(俗称:文件夹)
- 2. File类声明在java.io包下
- 3. File类中涉及到关于文件或文件目录的创建、删除、重命名、修改时间、文件大小等方法,并未涉及到写入或读取文件内容的操作。如果需要读取或写入文件内容,必须使用I0流来完成。
- 4.后续File类的对象常会作为参数传递到流的构造器中,指明读取或写入的”终点".
1.2 file的实例化
1.2.1 常用构造器
FiLe(String filePath)
File(String parentPath, String childPath )
File(File parentFile, String childPath)|
1.2.2 路径的分类
public String getAbsolutePath():获取绝对路径
public String getPath() :获取路径
public String getName() :获取名称
public String getParent(): 获取上层文件目录路径。若无,返回null
public long length() :获取文件长度(即:字节数)。不能获取目录的长度。
public long lastModified() :获取最后一次的修改时间,毫秒值
如下的两个方法适用于文件目录:
public String[] list() :获取指定目录下的所有文件或者文件目录的名称数组
public File[] listFiles() :获取指定目录下的所有文件或者文件目录的File数组
说明(IDEA适用):
如果大家开发使用JUnit中的单元测试方法测试,相对路径即为当前Module下。
如果大家使用main()测试,相对路径即为当前的Project下。
1.2.3 路径分隔符
路径中的每级目录之间用一个路径分隔符隔开。路径分隔符和系统有关:
- windows和DOS系统默认使用“\” 来表示
- UNIX和URL使用“1”来表示
Java程序支持跨平台运行,因此路径分隔符要慎用。为了解决这个隐患,File 类提供了一个常量:
public static final String separator。根据操作系统,动态的提供分隔符。
File file1 = new File("d: \\atguigu\\info. txt");
File file2 = new File("d:" +
File.separator + "atguigu" + File.separator + "info . txt" );
File file3 = new File("d:/atguigu");
1.3 file类的常用方法
- ➢public String getAbsolutePath():获取绝对路径
- ➢public String getPath(): 获取路径
- ➢public String getName() :获取名称
- ➢public String getParent():获取. 上层文件目录路径。若无,返回null
- ➢public long length(): 获取文件长度(即:字节数) 。不能获取 目录的长度。
- ➢public long lastModified():获取最后-次的修改时间,毫秒值
- ➢public String[] list():获取指定目录下的所有文件或者文件目录的名称数组
- ➢public File[] listFiles() :获取指定目录下的所有文件或者文件目录的File数组
- ➢public boolean renameTo(File dest):把文件重命名为指定的文件路径
- ➢public boolean isDirectory():判断是否是文件目录
- ➢public boolean isFile():判断是否是文件
- ➢public boolean exists() :判断是否存在
- ➢public boolean canRead() :判断是否可读
- ➢public boolean canWrite() :判断是否可写
- ➢public boolean isHidden() :判断是否隐藏
二、IO流
2.1 JAVA IO 原理
I/O是Input/Output的缩写, I/O技术是非常实用的技术,用于处理设备之间的数据传输。如读/写文件,网络通讯等。
Java程序中,对于数据的输入/输出操作以“流(stream)” 的方式进行。
java.io包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过标准的方法输入或输出数据。
2.1.1 流的分类
- 按操作数据单位不同分为: 字节流(8 bit),字符流(16 bit)
- 按数据流的流向不同分为: 输入流,输出流
- 按流的角色的不同分为: 节点流,处理流
2.1.2 IO流体系结构
2.1.3 字符集字符编码
- ASCII:——美国标准信息交换码。用一个字节的7位可以表示。
- IS08859-1——拉丁码表。欧洲码表。用一个字节的8位表示。
- GB2312——中国的中文编码表。最多两个字节编码所有字符
- GBK——中国的中文编码表升级,融合了更多的中文文字符号。最多两个字节编码
- Unicode——国际标准码,融合了目前人类使用的所有字符。为每个字符分配唯一的字符码。
- UTF-8——变长的编码方式,可用1-4 个字节来表示一个字符。
面向传输的众多UTF (UCS Transfer Format) 标准出现了,顾名思义,UTF-8就是每次8个位传输数据,而UTF-16就是 每次16个位。这是为传输而设计的编码,并使编码无国界,这样就可以显示全世界上所有文化的字符了。
Unicode只是定义了一个庞大的、全球通用的字符集,并为每个字符规定了唯一确定的编号,具体存储成什么样的字节流,取决于字符编码方案。推荐的Unicode编码是UTF-8和UTF-16。
三、对象流的使用
ObjectInputStream 和OjbectOutputSteam
➢用于存储和读取基本数据类型数据或对象的处理流。它的强大之处就是可以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来。
- 序列化——用ObjectOutputStream类 保存基本类型数据或对象的机制
- 反序列化——用ObjectInputStream类 读取基本类型数据或对象的机制
- ObjectOutputStream和ObjectnputStream不 能序列化static和transient修饰的成员变量
3.1 对象的序列化
3.1.1对象序列化机制
允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。当其它程序获取了这种二进制流,就可以恢复成原来的Java对象
3.1.2 序列化的好处
可将任何实现了Serializable接口的对象转化为字节数据,使其在保存和传输时可被还原
序列化是RMI ( Remote Method Invoke-远程方法调用)过程的参数和返回值都必须实现的机制,而RMI是JavaEE的基础。因此序列化机制是JavaEE平台的基础
3.1.3 如何序列化
如果需要让某个对象支持序列化机制,则必须让对象所属的类及其属性是可序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口之一。否则,会抛出NotSerializableException异常
- ➢Serializable
- ➢Externalizable
3.1.4 代码示例
import org.junit.Test;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class ObjectInputOutputStreamTest {
//序列化——将内存中的java对象保存到磁盘中或通过网络传输数据
@Test
public void testObjectOutputStream() {
try {
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("test.data"));
oos.writeObject(new String("我爱北京天安门"));
oos.flush(); //刷新操作
oos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void testObjectInputStream() {
try {
ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("test.data"));
Object obj = ois.readObject();
String str = (String) obj;
ois.close();
System.out.println(str);
} catch (Exception e) {
e.printStackTrace();
}
}
}
3.1.5 自定义类序列化的要求
凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量:
➢ private static final long serialVersionUID;
➢ serialVersionUID用来表明类的不同版本间的兼容性。简言之,其目的是以序列化对象进行版本控制,有关各版本反序列化时是否兼容。
➢如果类没有显示定义这个静态变量,它的值是Java运行时环境根据类的内部细节自动生成的。若类的实例变量做了修改,serialVersionUID 可能发生变化。故建议,显式声明。
简单来说,Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。(InvalidCastException)
Person需要满足如下的要求,方可序列化
- 1.需要实现接口: Serializable
- 2.当前类提供一个全局常量: serialVersionUID
- 3.除了当前Person类需要实现Serializable接口之外, 还必须保证其内部所有属性也必须是可序列化的。