如何将多个文件合并成一个文件?

huheng_0_0 2008-05-28 03:27:01
比如我的程序一共产生了3个文件,a.txt, b.xml, c.jpg, 如何将这个三个文件放在一个自定义文件中,我下次读取的时候,又应该怎么解析,分别得到这个三个文件?
...全文
619 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
huheng_0_0 2008-05-29
  • 打赏
  • 举报
回复
谢谢楼上,其实我不需要将两个文件合并,只是希望将他们捆绑,然后用一个“壳”包装他们,暴露给用户的就是这个壳而已。
如果你愿意,我也非常希望学习一下你的方法。 :)
Tll_W 2008-05-29
  • 打赏
  • 举报
回复
我随便选择了几个文件a.jpg和b.txt,然后我把他们两个分别读取并存到了一个文件中:c.tll,然后我用一个按钮,可以把c.tll分解到一个目录下,然后该目录下就是a.jpg和b.txt两个文件了.如果你是要这个效果,我可以给你些代码参考,如果不是,就当我帮你顶了,^_^
家鸣 2008-05-29
  • 打赏
  • 举报
回复
先生成一个Exe文件作为母版,然后把要捆绑的文件全都放到这个Exe的后面。具体过程就是:读入一个文件到Exe的未部,写入这个文件的大小,如此循环,直到所有文件绑定完毕。

运行时,这个Exe先检查自身文件的大小,如果这个Size不等于母版Exe文件自身,说明自身捆绑了文件,然后从未部根据文件的大小来释放文件,如此循环。
这过程在C++里验证通过。我想C#应该可以实现这样的功能。

另把其它文件写入到Exe的未部,并不改变Exe的文件结构,所以这个Exe文件还可以正常运行。
Tll_W 2008-05-29
  • 打赏
  • 举报
回复

struct CFileInfor
{
public string fileName;
public long fileLength;
}
long GetFileSize(string fileName)
{
FileInfo fi = new FileInfo(fileName);
if (fi != null && fi.Exists == true)
{
return fi.Length;
}
return -1;
}

byte[] GetFileBytes(string fileName)
{
byte[] bytes = null;
try
{
FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
bytes = new byte[fs.Length];
br.Read(bytes, 0, (int)fs.Length);
br.Close();
fs.Close();
}
catch
{ }
return bytes;
}

void CombineOneFile(string[] inFiles, string outFile)
{
FileStream fs = new FileStream(outFile, FileMode.CreateNew, FileAccess.Write);
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(inFiles.Length);

foreach (string inFile in inFiles)
{
string fileName = Path.GetFileName(inFile);
long fileSize = GetFileSize(inFile);
bw.Write(inFile);
bw.Write(fileSize);
}
foreach (string inFile in inFiles)
{
byte[] bytes = GetFileBytes(inFile);
bw.Write(bytes);
}
bw.Close();
fs.Close();
}

void SplitFromOneFile(string oneFile, string outPath)
{
if (Directory.Exists(outPath) == false)
{
Directory.CreateDirectory(outPath);
}
FileStream fs = new FileStream(oneFile, FileMode.Open, FileAccess.Read);
int count = 0;
BinaryReader br = new BinaryReader(fs);
count = br.ReadInt32();
CFileInfor[] files = new CFileInfor[count];
for (int i = 1; i <= count; i++)
{
files[i - 1] = new CFileInfor();
files[i - 1].fileName = br.ReadString();
files[i - 1].fileLength = br.ReadInt64();
}
foreach (CFileInfor file in files)
{
byte[] bytes = null;
bytes = br.ReadBytes((int)file.fileLength);
FileStream fsTemp = new FileStream(outPath + "\\" + file.fileName, FileMode.Create, FileAccess.Write);
fsTemp.Write(bytes, 0, bytes.Length);
fsTemp.Close();
}
br.Close();
fs.Close();
}
huheng_0_0 2008-05-28
  • 打赏
  • 举报
回复
当然可以采取把这三个文件放入一个文件夹,然后调用ziplib压缩这个文件夹,然后更改后缀名。但是有没有别的办法呢?
请问ChrisAK,你说的.net自带的,能稍微详细一点吗,或者链接。
huheng_0_0 2008-05-28
  • 打赏
  • 举报
回复
不知道我是不是没有理解大家的意思,还是我没说清楚,我并不需要对这三个文件进行压缩或者更改,我只是希望,这3个文件不要分散放置,而是像放在一个文件夹里一样,但是暴露给用户的,仅到这个所谓的文件夹级别。
ChrisAK 2008-05-28
  • 打赏
  • 举报
回复
要压缩的话就找找#ziplib之类的开源格式.
懒的话.net自己带的资源文件格式也不错,而且读写都是库直接支持的.

不嫌麻烦的话自己写也不错.
gomoku 2008-05-28
  • 打赏
  • 举报
回复

private void button1_Click(object sender, EventArgs e)
{
Packer.Pack(@"c:\temp\all.dat", @"c:\temp\a.bat", @"c:\temp\a.jpg");
string[] resultFiles = Packer.Unpack( @"c:\temp\all.dat" );

MessageBox.Show( string.Join("\n", resultFiles), "files generated under the current directory");
}


public class Packer
{
class Header
{
public long length;
public string filename;

public void WriteTo( Stream fs )
{
byte[] len = BitConverter.GetBytes(length);
byte[] buf = new byte[256];

byte[] str = Encoding.Unicode.GetBytes(filename);
str.CopyTo(buf, 0);

fs.Write(len, 0, len.Length);
fs.Write(buf, 0, buf.Length);
}
public bool ReadFrom( Stream fs)
{
byte[] len = BitConverter.GetBytes(length);
byte[] buf = new byte[256];

if (len.Length != fs.Read(len, 0, len.Length)) return false;
if (buf.Length != fs.Read(buf, 0, buf.Length)) return false;

length = BitConverter.ToInt64(len, 0);
filename = Encoding.Unicode.GetString(buf).Trim(new char[] { '\0' });
return true;
}
}

public static void Pack(string resultFilename, params string[] filenames)
{
using (FileStream fout = new FileStream(resultFilename, FileMode.Create, FileAccess.Write))
{
for (int i = 0; i < filenames.Length; i++)
{
using (FileStream fin = new FileStream(filenames[i], FileMode.Open))
{
Header header = new Header();
header.length = fin.Length;
header.filename = Path.GetFileName(filenames[i]);
header.WriteTo(fout);

byte[] buf = new byte[header.length];
fin.Read(buf, 0, buf.Length);
fout.Write(buf, 0, buf.Length);
}
}
}
}

public static string[] Unpack(string filename)
{
List<string> unpackedFiles = new List<string>();

using (FileStream fin = new FileStream(filename, FileMode.Open, FileAccess.Read))
{
Header header = new Header();
while (header.ReadFrom(fin))
{
unpackedFiles.Add(header.filename);
byte[] buf = new byte[header.length];
fin.Read(buf, 0, buf.Length);

using (FileStream fout = new FileStream(header.filename, FileMode.Create, FileAccess.Write))
{
fout.Write(buf, 0, buf.Length);
}
}
}
return unpackedFiles.ToArray();
}
}

kingstou 2008-05-28
  • 打赏
  • 举报
回复
用ZIP庫
marvelstack 2008-05-28
  • 打赏
  • 举报
回复
最简洁的做法,如微软的新Office文档格式,使用压缩包。
huheng_0_0 2008-05-28
  • 打赏
  • 举报
回复
可能我没有表达清楚,其实我的意思是不要改变这三个文件,只是相当于做了一个zip文件一样,把这三个文件放在里面,用winRar压缩文件管理器查看的时候,可以看见这个三个独立的文件,只是外面看,这是一个叫做combination.cbn(自定义)的文件而已。:)
baihe_591 2008-05-28
  • 打赏
  • 举报
回复


private void hebin()
{
int data=0;
FileStream targefile = new FileStream("a.txt", FileMode.Append , FileAccess.Write);
FileStream newfile = new FileStream("b.txt", FileMode.OpenOrCreate, FileAccess.Read);
byte [] buffer=new byte [newfile .Length ];
while ((data= newfile .Read (buffer ,0,(int)newfile .Length ))>0)
{
targefile .Write (buffer ,0,(int )newfile .Length );
}
newfile .Close ();
targefile .Close ();
}
Tll_W 2008-05-28
  • 打赏
  • 举报
回复
我说下我的思路啊。。。
文件个数
文件名,文件长度
文件名,文件长度
......
文件名,文件长度
文件二进制流
例如:
3
a.txt,1435
b.xml,12334
c,jpg,234920
234920+1435+12334个字节
读取的时候方法:
先读取3
之后读取3行:文件名和长度
最后把后面的二进制流读到byte[] bytes中,然后截断分别写入文件就ok
baihe_591 2008-05-28
  • 打赏
  • 举报
回复
将文件内容转换成二进制,追加到目标文件里面.
源码链接: https://pan.quark.cn/s/0f7c75cb3aad ### MIPI Video Mode 与 Command Mode 的差异 #### 一、引言 MIPI (Mobile Industry Processor Interface) 是一种用于连接移动设备中处理器及其外围设备的标准化接口。MIPI 接口支持多种协议,其中包含 DSI (Display Serial Interface) 和 DCS (Display Control Interface) 等协议。在 MIPI 接口的应用中,主要涉及两种工作模式:Video Mode(视频模式)和 Command Mode(命令模式)。本文旨在系统性地阐述这两种模式的工作机制、特性以及实际应用环境。 #### 二、LCD RAM 概念说明 在进一步探讨 MIPI 的两种模式之前,有必要对文中提及的“LCD RAM”概念进行明确。实际上,“LCD RAM”并非一个通用术语,而是本文作者用来描述 LCD 控制器中用于存储显示数据的内存区域。LCD(Liquid Crystal Display,液晶显示屏)通常配备一个控制 IC(Integrated Circuit,集电路),该控制 IC 可能内置 RAM 以缓存显示数据。 #### 三、MIPI Video Mode(视频模式) **定义:** - 视频模式是一种类似于传统 RGB 接口的工作模式,它要求主机持续不断地向显示器传输刷新数据。 - 在这种模式下,数据和控制信号以报文的形式通过 MIPI 总线进行传输。 - 显示器本身无需配备帧缓冲器,因为主机会周期性地刷新屏幕。 **特点:** 1. **实时性高:** 主机需要不...
源码下载地址: https://pan.quark.cn/s/a4b39357ea24 在电磁模拟技术中,CST(Computer Simulation Technology)是一种被广泛采纳的软件工具,它主要用于电磁场、微波、天线以及射频系统的设计工作。本资料将详细分析CST软件中离散端口的具体配置方法,这些方法对于提升仿真结果的精确度和专业水准具有决定性作用。离散端口在CST软件中扮演着模拟信号输入或输出的重要角色,它们构了仿真模型不可或缺的部分。在配置离散端口时,一个核心的原则是保证端口的方向与网格线保持一致,这是因为这样做能够有效降低计算过程中产生的误差,并确保仿真数据的有效性。如果未能遵循这一指导原则,可能会引发未知的计算问题,进而导致仿真结果失去可靠性。 在CST软件中配置离散端口,通常需要借助“Pick Points”这一功能。通过选择“Pick Edge Center”选项,端口将被设定在模型边缘的中心位置上。然而,这种做法并不总是能够确保端口与网格线保持平行。在某些特定情形下,模型的几何构造可能不允许直接选取一个与网格线平行的边作为端口的安装位置。 为了克服这一挑战,可以采用多种不同的策略。如果模型本身已经包含一条与馈电口平行的边,那么可以直接利用这条边来建立端口,此时CST软件会自动调整端口使其与网格线对齐。另一种可选的方法是,当模型不具备现的平行边时,用户可以手动构建一个几何结构,比如一个立方体,并使其边缘与馈电口平行。通过这种方式,新建立的几何结构的边缘就可以作为端口的位置,从而确保端口与网格线的平行关系。 在实施上述操作时,必须关注端口尺寸的合理性和物理意义的一致性。端口的尺寸应当依据实际天线馈电部分的尺寸进行适当调整,过大的端口或...
代码下载链接: https://pan.quark.cn/s/a4b39357ea24 【使用TensorFlow进行图像识别】 图像识别作为计算机视觉领域的关键任务之一,其核心在于通过算法解析和理解图像所包含的信息。在此资源中,我们将集中探讨如何借助功能强大的深度学习框架TensorFlow来执行手写数字识别。手写数字识别构了众多实际应用的基础,例如自动支票处理、光学字符识别(OCR)等场景。 TensorFlow是由Google创建的一个开源库,它主要用于数值运算和机器学习,尤其在深度学习方面表现卓越。其核心优势在于可以构建并训练复杂的神经网络架构,并且在多种硬件环境中实现高效执行,涵盖CPU和GPU平台。 在此实践项目中,我们将运用TensorFlow来构建一个卷积神经网络(CNN)模型,这种架构是处理图像数据的理想选择。CNNs通过模仿人脑视觉皮层的运作机制,能够自主地提取图像中的关键特征,进而达识别目标。在手写数字识别的特定情境下,这些特征可能涉及笔画的几何形态、走向以及相互间的连接模式。 对于CNN的基础结构,我们需要具备相应的认知,其通常由卷积层、池化层、全连接层以及激活函数等部分组。卷积层借助滤波器(亦称卷积核)对图像进行扫描,以捕捉局部特征;池化层则用于降低数据维度,同时保留核心信息;全连接层将特征向量映射至各类别的概率分布;而激活函数如ReLU则通过引入非线性元素,使模型能够学习更为复杂的模式。 在此案例中,建议采用MNIST数据集,这是一个广泛用于手写数字识别的标准测试集。该数据集包含60,000个训练样本和10,000个测试样本,每个样本均为28x28像素的灰度图像,代表0到9这十个数字中的某一个。为了训练模型,必须首先加载数据,并...

111,129

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧