VBA解析复合文档06——改写数据流
时间:2022-07-22
本文章向大家介绍VBA解析复合文档06——改写数据流,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
改写数据流和读取是类似的,只需要逐个扇区去处理就可以,需要注意的是,如果改写的数据长度比原来的数据长度变大了,这时候要注意是否会超越扇区的边界,如果超过了,那么就得改变文件的长度,处理起来就会很麻烦了,这种情况暂时就不进行改写。
'改写数据流
'dir_name 需要被改写的文件名称,是复合文档中的文件名称
'WriteBytes 需要改写为的数据Byte数组
'Return 返回出错信息
Function ReWriteStream(dir_name As String, WriteBytes() As Byte) As String
If cf.h.Exists(dir_name) Then
ReWriteStream = ReWriteStreamByDirIndex(VBA.CLng(cf.h.GetItem(dir_name)), WriteBytes)
Else
ReWriteStream = "复合文档:不存在的目录"
Exit Function
End If
End Function
Private Function ReWriteStreamByDirIndex(dirIndex As Long, WriteBytes() As Byte) As String
'1仓storage 2流 5根
If cf.ArrDir(dirIndex).ObjectType <> 2 Then
ReWriteStreamByDirIndex = "复合文档:不是数据流"
Exit Function
End If
If cf.ArrDir(dirIndex).StartingSectorID = Free_SID Then
ReWriteStreamByDirIndex = "复合文档:流的大小为0"
Exit Function
End If
Dim ilen As Long
ilen = UBound(WriteBytes) + 1
If cf.ArrDir(dirIndex).StreamSize < cf.Header.MiniStreamSize Then
ReWriteStreamByDirIndex = ReWriteStreamMiniFAT(dirIndex, WriteBytes)
Else
ReWriteStreamByDirIndex = ReWriteStreamFAT(dirIndex, WriteBytes)
End If
'改写目录stream_size
cf.ArrDir(dirIndex).StreamSize = ilen
cf.r.SeekFile cf.ArrDir(dirIndex).lOffset + DIR_SIZE - 8, OriginF
cf.r.WriteLong ilen
End Function
Private Function ReWriteStreamMiniFAT(dirIndex As Long, WriteBytes() As Byte) As String
Dim ilen As Long
ilen = UBound(WriteBytes) + 1
'如果改写的数据超过了原来的范围,并且超越了扇区,需要报错
If ilen > cf.ArrDir(dirIndex).StreamSize Then
If ilen cf.lShortSectorSize > cf.ArrDir(dirIndex).StreamSize cf.lShortSectorSize Then
ReWriteStreamMiniFAT = "复合文档:改写的数据超过了原来的范围,并且超越了扇区"
Exit Function
End If
End If
Dim b() As Byte
ReDim b(cf.lShortSectorSize - 1) As Byte
'找到改写开始的位置
Dim miniSID As Long
miniSID = cf.ArrDir(dirIndex).StartingSectorID
Dim i As Long
Dim p As Long
Do Until miniSID = End_Of_Chain_SID
'设置改写的位置
cf.r.SeekFile getOffsetByMiniFATSID(miniSID), OriginF
cf.r.Read b
For i = 0 To cf.lShortSectorSize - 1
b(i) = WriteBytes(p)
p = p + 1
If p = ilen Then
ReDim Preserve b(p Mod cf.lShortSectorSize - 1) As Byte
cf.r.WriteFile b
Exit Function
End If
Next
cf.r.WriteFile b
'下一个扇区
miniSID = cf.MiniFAT(miniSID)
Loop
End Function
Private Function ReWriteStreamFAT(dirIndex As Long, WriteBytes() As Byte) As String
Dim ilen As Long
ilen = UBound(WriteBytes) + 1
'如果改写的数据超过了原来的范围,并且超越了扇区,需要报错
If ilen > cf.ArrDir(dirIndex).StreamSize Then
If ilen cf.lSectorSize > cf.ArrDir(dirIndex).StreamSize cf.lSectorSize Then
ReWriteStreamFAT = "复合文档:改写的数据超过了原来的范围,并且超越了扇区"
Exit Function
End If
End If
'找到改写开始的位置
Dim sid As Long
sid = cf.ArrDir(dirIndex).StartingSectorID
Dim i As Long
Dim p As Long
Dim b() As Byte
ReDim b(cf.lSectorSize - 1) As Byte
Do
'设置改写的位置
cf.r.SeekFile getOffsetBySID(sid), OriginF
For i = 0 To cf.lSectorSize - 1
b(i) = WriteBytes(p)
p = p + 1
If p = ilen Then
ReDim Preserve b(p Mod cf.lSectorSize - 1) As Byte
cf.r.WriteFile b
Exit Function
End If
Next
cf.r.WriteFile b
'下一个扇区
sid = cf.FAT(sid)
Loop
End Function
- Java并发编程的艺术(三)——volatile
- java学习手册-java 新手入门必看的30个题
- Java并发编程的艺术(五)——中断
- 简易的深度学习框架Keras代码解析与应用
- Java并发编程的艺术(六)——线程间的通信
- 轻量级线程池的实现
- python根据BM25实现文本检索
- 稳扎稳打JavaScript(一)——作用域链内存模型
- 稳扎稳打JavaScript(二)——图解对象内存模型
- Swift学习资源
- 稳扎稳打JavaScript(三)——创建对象的几种方式
- 快速教程:使用Cython来扩展Python/NumPy库
- 稳扎稳打JavaScript(四)——闭包
- JavaScript奇淫技巧(一)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Hive初步使用、安装MySQL 、Hive配置MetaStore、配置Hive日志《二》
- Python - lambda函数
- Oracle 基础学习笔记
- 算法【最大子序列问题】
- 【算法、递归回溯解决数独】
- Anaconda使用命令
- 最大连续子数组
- markdown编辑器实现代码高亮
- LeetCode - 198 简单动态规划 打家劫舍
- Jaskson精讲第7篇-JsonTypeInfo注解在类继承关系下的使用
- 《剑指Offer 1.二维数组中的查找》2019-03-25
- Elasticsearch:Dynamic mapping
- 设计模式《单例设计模式》
- 《0-1 背包问题》
- 使用分治思想 求数组中的最大和最小值