首页 > 语言 > 关键词  > .net教程最新资讯  > 正文

.Net实现合并文件

2010-12-29 14:41 · 稿源:cyclone,www.cnblogs.com/cyclone-dll

以上列表中的文件并不是来自于某个文件夹中的所有jpg文件,而是来自于这个文件。

将多个文件合并为一个文件在许多应用领域都十分有用。亲自实现这样一个程序一定不但过瘾且在许多时候可以帮助我们构建更高效的程序。这里我做了一个方案例分享给大家。

由于合并后的文件就像一个包裹,所以下文中都把这样的文件称为“包文件”

主构思:

要把多个文件合并成一个包文件,还要可以区分其中的某个文件并提取出来。我们需要知道文件的名称和这个文件在包文件中的位置及长度,也就是所谓的地址偏移。

由于包文件常常会比较大,所以不应该让它的内容常驻于内存,只应该需要某部分的时候再从包文件中提取。

我是这样做的:

一个管理器类,提供一些外围的方法

_pathList用于存放要添加到包文件的文件路径,通过调用AddSourceFile()方法添加

_pf 是具体的包文件,通过LoadPackFile() 生成实例,通过CurrentPackFile属性返回

Build方法用于生成包文件

PackFile类作为PackFileManager的嵌套类,它提供包文件的属性和施工细节。

好了,我们先来看看PackFileManager.Build()方法

以下为引用的内容:

public void Build(string path)

{

using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write))

{

BinaryWriter bw = new BinaryWriter(fs);

bw.Write("PackFile");

bw.Write(this._pathList.Count);

foreach (string f in this._pathList)

{

FileInfo fi = new FileInfo(f);

bw.Write(fi.Length);

fi = null;

}

foreach (string f in this._pathList)

{

bw.Write(Path.GetFileName(f));

}

foreach (string f in this._pathList)

{

bw.Write(File.ReadAllBytes(f));

bw.Flush();

}

}

}

1. 先写个“PackFile”字符串到文件头

2. 把以Int32为类型的,要输出到包文件中的文件数量写入

3. 把以long为类型的,要输出到包文件中的每个文件的长度写入。

4. 再把每个文件名写入

5. 最后写入每个文件的实体内容。

由于在写或读时不频繁在Write方法或ReadXXX方法的不同版本间频繁切换,所以我想这样组织文件结构可以更高效一些。

疑问来了。在写入文件名的时候,我们使用bw.Write(Path.GetFileName(f));

调用了BinaryWriter.Write(string value),传入的是字符串,那么在读取的时候要调用BinaryReader.ReadString()。这时它是如何区分两个字符串边界的。还好,Write方法会先将字符串长度作为一个四字节无符号整数写入,于是在用BinaryReader.ReadString()的时候它会根据这个值来读取特定长度的值,并理解为字符串。

这里列出几个重要方法:

以下为引用的内容:

PackFileManager的LoadPackFile方法

public void LoadPackFile(string path)

{

if (!File.Exists(path))

{

throw new FileNotFoundException(path);

}

if (_pf != null)

{

_pf.Close();

_pf = null;

}

FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);

BinaryReader br = new BinaryReader(fs);

if (br.ReadString() != "PackFile")

{

throw new InvalidCoalescentFileException("该文件不是有效的包文件");

}

this._pf = new PackFile(fs,br);

}

此时,我们在生成时写入的字符串"PackFile" 就有了明确的功能

PackFile的构造函数

以下为引用的内容:


internal PackFile(FileStream srcFile,BinaryReader br)

{

this._sourceFile = srcFile;

_br = br;

this._fileCount = _br.ReadInt32();//取文件数

for (int i = 1; i <= _fileCount; i++)

{

this._fileLengthList.Add(_br.ReadInt64());

}

for (int i = 1; i <= _fileCount; i++)

{

this._shortNameList.Add(_br.ReadString());

}

this._contentStartPos = _sourceFile.Position;//设置实体文件总起始位置

}

PackFile.GetBytes()

public byte[] GetBytes(int index)

{

long startPos = this._contentStartPos;

for (int i = 0; i < index; i++)

{

startPos += this._fileLengthList[i];

}

_sourceFile.Position = startPos; //设置某文件内容的起始位置

return _br.ReadBytes((int)_fileLengthList[index]);

}

这只是一个草案,我们还可以加入压缩、或是像ZIP文件那样的嵌套文件夹功能,改进后的代码别忘与我分享哦。

代码下载:测试并合文件

我们来总结一下:

纵观代码可以发现,核心功能都在围绕“偏移位置”与“长度”两个概念,这在数据结构中很重要。同时,这也提醒了我们为什么在数据库表字段中,作为主键的只能是“定长”类型,而不能是“变长”类型。(来源:cyclone

举报

  • 相关推荐
  • 聚焦大模型训练效率提升 北大依托昇腾突破细粒度混合并行技术

    北京大学崔斌教授团队在鹏城实验室支持下,研发了面向大模型的高效分布式训练框架。该框架通过统一训练接口、细粒度模型切分与并行策略搜索算法,解决了训练任务多样性和负载不均问题,实现训练效率提升15%。同时利用昇腾计算资源管理能力,优化硬件通信效率,通过计算通信重叠技术提升流水线效率。研究成果已在NeurIPS等顶会发表3篇论文,展现了国产算力在分布式计算领域的潜力,为AI产业自主化突破提供支撑。

  • steam账号注册教程——全网最新最全的方法

    本文介绍了Steam平台注册及下载安装的完整教程。主要内容包括:1.使用迅 游加速器优化网络环境,解决注册过程中的错误提示;2.详细说明客户端下载安装步骤,强调要选择简体中文和避开中文路径;3.分步指导账户注册流程,包括邮箱验证、地区选择和人机验证;4.提醒全程使用加速器保持网络稳定,避免注册中断。教程旨在帮助新手玩家顺利注册Steam账号并下载游戏,提升�

  • 安卓迎来大变化:ChromeOS将跟安卓合并

    谷歌安卓生态系统总裁Sameer Samat确认,谷歌将会把ChromeOS与安卓系统整合为一个平台,不过Sameer Samat并未透露该计划的更多细节,消息称谷歌的计划是将ChromeOS迁移至安卓系统。 目前安卓系统已经支持大屏设备,提供完善的桌面模式、桌面窗口,还支持外接显示器,同时优化了应用适配,让应用在不同尺寸的屏幕上都能得到较好的适配和体验。 资料显示,ChromeOS是谷歌开

  • 文远知行与阿布扎比综合交通中心合作,扩大Robotaxi在阿运营范围

    2025年7月29日,文远知行与Uber合作在阿布扎比推出Robotaxi服务,覆盖阿尔雷姆岛和阿尔马里亚岛等核心区域。这是中东地区规模最大的自动驾驶车队,采用文远知行新一代GXR车型,每车可载5人。服务范围已覆盖阿布扎比近半核心区,包括主要住宅区和商业中心。自2024年12月启动以来,车队规模已增长三倍,日均完成数十次订单。该项目是阿布扎比智能交通战略的重要部分,目标到2040年实现25%公共交通依赖智能出行。合作方表示,这将推动自动驾驶技术在中东地区的主流化应用。

  • 战地6测试资格免费领 超简单百分百一键领取测试资格教程 限量免费领

    《战地6》测试资格今日开放领取。玩家需通过抖音平台搜索游戏官号,在相关图文下获取资格链接,完成领取后通过EA平台激活游戏参与测试。为避免网络问题影响游戏体验,建议使用加速器优化本地网络环境。本文详细介绍了资格领取步骤,帮助玩家顺利参与本次测试。

  • 明末渊虚之羽帧数低怎么提高?附明末画面设置教程,低配机也能畅玩!

    《明末:渊虚之羽》是一款国风克苏鲁魂类ARPG游戏,玩家将扮演失忆女侠"无常",游戏背景基于中国古蜀文明,融合三星堆、金沙等真实遗址元素。文章主要提供游戏帧数优化方案:1.使用迅游加速器优化网络环境;2.下载"帧数大师"工具自动调节帧率;3.手动修改游戏文件禁用全屏优化;4.详细画面设置建议:关闭动态模糊、降低阴影质量、调整全局光照等;5.针对不同显卡(DLSS/FSR/TSR)的超分辨率技术选择建议。游戏即将登陆Steam/Xbox等平台,优化设置可显著提升游戏流畅度。

  • Matrixport CEO John 出席 Foresight 2024 年度峰会,表示Matrixport将持续拥抱合规,提供专业资管服务

    Matrixport CEO John Ge在"Foresight2024"峰会上表示,合规化是加密行业主旋律。他指出当前加密市场缺乏新流量入场,资产管理趋向主流资产集中化,BTC、ETH等占比很高。随着加密ETF通过,合规属性增强,跨圈资管开始复苏。Matrixport将持续拥抱合规,为更多用户提供专业资管服务,帮助用户获取理性收益。公司成立于2019年,是亚洲最大的一站式加密金融服务平台,致力于构建�

  • Cactus Custody 与 Bybit 达成战略合作,提升加密安全系数

    7月23日,Matrixport旗下合规数字资产托管商Cactus Custody宣布与Bybit达成战略合作,其场外结算系统Cactus Oasis将于7月28日正式接入Bybit平台。该系统专为机构客户设计,融合资产安全托管与高效结算功能,用户无需预充值交易所账户,只需将抵押资产存入托管账户即可交易。合作将提升加密投资者的交易体验,降低交易对手风险。Cactus Custody持有香港信托公司牌照,采用冷热钱包分层架构和银行级存储设施,并通过SOC1/2审计认证,确保资产安全合规。双方表示此次合作将加速机构资金入场,推动加密行业机构化进程。

  • 上上签加入日本AILTA,共建可信AI与数字合规新范式

    中国电子签约行业领军服务商上上签电子签约(BestSign)宣布加入日本AI法律技术协会(AILTA),成为该组织正式会员。此举标志着上上签在国际合规生态中的进一步深耕,也意味着其将在AI法律技术和数字签约标准建设中持续发挥"互信合规"的中国方案作用。AILTA是日本LegalTech领域最具代表性的行业协会平台,上上签加入后将与协会在AI合同审查、风险条款识别、数据保护机制等多个方向开展联合研究。上上签CEO万敏表示,加入AILTA是从技术服务走向合规共建的重要一步,未来电子签约比拼的将不仅是功能多少,而是对本地文化、商业伦理、合规诉求的理解深度。

  • 腾讯云自研操作系统TencentOS与中国金融认证中心达成合作,全面支持安全启动

    腾讯云操作系统TencentOS Server V4全面支持安全启动(Secure Boot)功能,通过与微软和中国金融认证中心(CFCA)合作,实现双轨并行的安全启动方案。该系统不仅获得微软签名认证,还基于CFCA国产根证书体系完成适配,构建从固件到操作系统的完整信任链。TencentOS团队严格遵循安全规范,对密钥实施严格保护,确保系统启动各环节安全验证,有效防御底层恶意软件攻击。该方案支持"开箱即用",无需额外配置即可在主流服务器和虚拟化平台运行,大幅提升部署效率与安全防护水平。