java基础(八)IO流

目录

一、file类

1.1 基本概念

1.2 file的实例化

1.2.1 常用构造器

1.2.2 路径的分类

1.2.3 路径分隔符

1.3 file类的常用方法

二、IO流

2.1 JAVA IO 原理

2.1.1 流的分类

2.1.2 IO流体系结构

2.1.3 字符集字符编码

三、对象流的使用

3.1 对象的序列化

3.1.1对象序列化机制

3.1.2 序列化的好处

3.1.3 如何序列化

3.1.4 代码示例

3.1.5 自定义类序列化的要求


 

 

一、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接口之外, 还必须保证其内部所有属性也必须是可序列化的

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值