流与文件

java 流定义:可以从中读入一个字节序列的对象称为 输入流;可以向其写入字节序列的是 输出流
主要有2种基类:InputStream 、OutputStreamReader、WriterInputStream 、OutputStream处理单字节的字符;Reader、Writer处理 两字节的Unicode码元。
InputStream 的read方法读入一个字节,OutputStream的write方法写入一个字节;read 和writer方法执行的时候线程都会阻塞。
注意 流打开后都需要close;OutputStream最后必须调用flush函数,将所有缓冲数据发送到目的地

流家族

流家族可以通过这两张图分成2大类
在这里插入图片描述
在这里插入图片描述

组合流过滤器

假设有这样一个场景:我们需要从一个数据文件 中读取数据。
首先我们确定最外层的类:因为要读取数值,所以选择DataInputStream;我们需要从文件中获得数据流,所以里面使用FileInputStream 从文件中获得输入流;为了提高效率,我们需要增加一个缓冲区,所以中间加一个BufferedInputStream;所以最终的代码就是

DataInputStream din = new DataInputStream(
	new BufferedInputStream(
		new FileInputStream("employee.data")));

文本输入输出

文本输出使用的类是PrintWriter;使用:

PrintWriter pw= new PrintWriter("test.txt");
//或者
PrintWriter pw= new PrintWriter(new FileWriter("test.txt"));
pw.print("test")
pw.print(' ')
pw.println()

PrintWriter和打印到终端的System.out类似;其他api可以查文档;注意如果没有设置自动println不会flush;

文本读入有两种方式:
通过BufferedReader和Scanner;感觉没啥好说的,很简单。

BufferedReader bf= new BufferedReader(new InputStreamReader(new FileInputStream("test.txt"),"UTF-8"))

对象序列化

java的序列化主要是通过实现serializable接口实现的但是,其实我们可以修改默认的序列化方式。

修改默认的序列化机制

对于序列化的对象,我们可以将他的域标记成transient,这样的对象在序列化的过程中会被跳过;
我们可以通过复写readObject和writeObject类,向默认的读写行为添加验证或者任何其他想要的行为

private void writeObject(ObjectInputStream in) throw IOException,ClassNotFoundException
private void readObject(ObjectOutputStream out) throw IOException

对象还可以实现Externalizable 接口,需要实现它的两个方法:

private void writeExternal(ObjectInputStream in) throw IOException,ClassNotFoundException
private void readExternal(ObjectOutputStream out) throw IOException

需要注意的是,这两个方法和readObject和writeObject不一样的是,这两个方法对包括超类在内的对象数据恢复和存储负全责,而序列化就是在流中仅仅记录所属对象所属的类。

单例和类型安全的枚举序列化

假设需要序列化这样的枚举

public class Orientation{
public static final Orientation HORIZONTAL = new Orientation(1);
public static final Orientation VERTICAL = new Orientation(2);
private int value;
private Orientation(int v){
value = v;
}

}

可以使用==来判断是不是相等;但是序列化后会变成一个新的对象,所以这样的==是不相等的;那么我们需要定义一种readResolve的机制。

protected Object readResolve() throws ObjectStreamException{
if(value ==1) return Orientation.HORIZONTAL;
if(value == 2) return Orientation.VERTICAL;
return null;
}

对象序列化版本管理

首先必须提供一个静态的serialVersionUID 变量,就不需要再计算其指纹,这样就可以读取不同版本的类对象。
对象流将尽力 将流对象转换成这个类当前的版本,对象流只会 考虑非瞬时和非静态的数据域
如果这两部分数据域之间名字匹配而类型不匹配,那么对 象流不会尝试将一种类型转换成另一种类型,因为这两个对象不兼容;如果流中的对象具有 在当前版本中所没有的数据域,那么对象流会忽略这些额外的数据;如果当前版本具有在流化对象中所没有的数据域,那么这些新添加的域将被设置成它们的默认值(如果是对象则是 null,如果是数字则为 0,如果是 boolean 值则是 false)。

序列化用于克隆对象

其做法很简单:直接将对象序列化到输出流中,然后将其读回。这样产生 的新对象是对现有对象的一个深拷贝(deep copy)。但是它通常会比显式地构建新对象并复制或克 隆数据域的克隆方法慢得多。

Files 和Path

简单说就是很方便的工具类,可以用的时候自己再看;不需要什么文件操作都通过file来做

文件内存映射

定义:利用虚拟内存将一个文件或者文件的一部分映射到虚拟内存中,然后就可以将这个文件当做数组一样的访问。
文件内存映射关键的一个类是FIleChannel,它使我们能够访问内存映射,文件加锁机制以及文件间数据快速传递等操作系统特性。

FileChannel类可以得到一个ByteBuffer对象,这样就可以很好地操作文件了

在对文件的读写时。可以通过FileChannel类实现文件的加锁。
一般实现方式

try(FileLock lock = channel.lock()){
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言是一种广泛使用的编程语言,它具有高效、灵活、可移植性强等特点,被广泛应用于操作系统、嵌入式系统、数据库、编译器等领域的开发。C语言的基本语法包括变量、数据类型、运算符、控制结构(如if语句、循环语句等)、函数、指针等。在编写C程序时,需要注意变量的声明和定义、指针的使用、内存的分配与释放等问题。C语言中常用的数据结构包括: 1. 数组:一种存储同类型数据的结构,可以进行索引访问和修改。 2. 链表:一种存储不同类型数据的结构,每个节点包含数据和指向下一个节点的指针。 3. 栈:一种后进先出(LIFO)的数据结构,可以通过压入(push)和弹出(pop)操作进行数据的存储和取出。 4. 队列:一种先进先出(FIFO)的数据结构,可以通过入队(enqueue)和出队(dequeue)操作进行数据的存储和取出。 5. 树:一种存储具有父子关系的数据结构,可以通过中序遍历、前序遍历和后序遍历等方式进行数据的访问和修改。 6. 图:一种存储具有节点和边关系的数据结构,可以通过广度优先搜索、深度优先搜索等方式进行数据的访问和修改。 这些数据结构在C语言中都有相应的实现方式,可以应用于各种不同的场景。C语言中的各种数据结构都有其优缺点,下面列举一些常见的数据结构的优缺点: 数组: 优点:访问和修改元素的速度非常快,适用于需要频繁读取和修改数据的场合。 缺点:数组的长度是固定的,不适合存储大小不固定的动态数据,另外数组在内存中是连续分配的,当数组较大时可能会导致内存碎片化。 链表: 优点:可以方便地插入和删除元素,适用于需要频繁插入和删除数据的场合。 缺点:访问和修改元素的速度相对较慢,因为需要遍历链表找到指定的节点。 栈: 优点:后进先出(LIFO)的特性使得栈在处理递归和括号匹配等问题时非常方便。 缺点:栈的空间有限,当数据量较大时可能会导致栈溢出。 队列: 优点:先进先出(FIFO)的特性使得

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值