如何将多个文件合并成一个文件? 比如我的程序一共产生了3个文件,a.txt, b.xml, c.jpg, 如何将这个三个文件放在一个自定义文件中,我下次读取的时候,又应该怎么解析,分别得到这个三个文件? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 我说下我的思路啊文件个数文件名,文件长度文件名,文件长度......文件名,文件长度文件二进制流例如:3a.txt,1435b.xml,12334c,jpg,234920234920+1435+12334个字节读取的时候方法:先读取3之后读取3行:文件名和长度最后把后面的二进制流读到byte[] bytes中,然后截断分别写入文件就ok 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 (); } 可能我没有表达清楚,其实我的意思是不要改变这三个文件,只是相当于做了一个zip文件一样,把这三个文件放在里面,用winRar压缩文件管理器查看的时候,可以看见这个三个独立的文件,只是外面看,这是一个叫做combination.cbn(自定义)的文件而已。:) 最简洁的做法,如微软的新Office文档格式,使用压缩包。 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(); } } 要压缩的话就找找#ziplib之类的开源格式.懒的话.net自己带的资源文件格式也不错,而且读写都是库直接支持的.不嫌麻烦的话自己写也不错. 当然可以采取把这三个文件放入一个文件夹,然后调用ziplib压缩这个文件夹,然后更改后缀名。但是有没有别的办法呢?请问ChrisAK,你说的.net自带的,能稍微详细一点吗,或者链接。 我随便选择了几个文件a.jpg和b.txt,然后我把他们两个分别读取并存到了一个文件中:c.tll,然后我用一个按钮,可以把c.tll分解到一个目录下,然后该目录下就是a.jpg和b.txt两个文件了.如果你是要这个效果,我可以给你些代码参考,如果不是,就当我帮你顶了,^_^ 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(); } 先生成一个Exe文件作为母版,然后把要捆绑的文件全都放到这个Exe的后面。具体过程就是:读入一个文件到Exe的未部,写入这个文件的大小,如此循环,直到所有文件绑定完毕。运行时,这个Exe先检查自身文件的大小,如果这个Size不等于母版Exe文件自身,说明自身捆绑了文件,然后从未部根据文件的大小来释放文件,如此循环。这过程在C++里验证通过。我想C#应该可以实现这样的功能。另把其它文件写入到Exe的未部,并不改变Exe的文件结构,所以这个Exe文件还可以正常运行。 关于WebBrowser控件Navigate方法的问题 多线程协同问题,有难度 C#图像处理 哪位兄弟用过filezilla命令行下载 小弟向帅哥美女求助:如何实现以下这样的树(进去看看就知道啦) 我在vs2003中制作一个显示条形统计图的控件,想把它做成具有数据绑定功能的,请问应该怎样做呢? 请教两个问题,请各位朋友帮助解答!谢谢 c# 堆叠图 怎么实现拖拉画圆(见图) 一个很怪异的问题.(DataGrid显示) 打开上传到Upload文件夹下面的莫个文件 c#获取系统制造商
文件个数
文件名,文件长度
文件名,文件长度
......
文件名,文件长度
文件二进制流
例如:
3
a.txt,1435
b.xml,12334
c,jpg,234920
234920+1435+12334个字节
读取的时候方法:
先读取3
之后读取3行:文件名和长度
最后把后面的二进制流读到byte[] bytes中,然后截断分别写入文件就ok
{
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 ();
}
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();
}
}
懒的话.net自己带的资源文件格式也不错,而且读写都是库直接支持的.不嫌麻烦的话自己写也不错.
请问ChrisAK,你说的.net自带的,能稍微详细一点吗,或者链接。
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();
}
这过程在C++里验证通过。我想C#应该可以实现这样的功能。另把其它文件写入到Exe的未部,并不改变Exe的文件结构,所以这个Exe文件还可以正常运行。