比如我的程序一共产生了3个文件,a.txt, b.xml, c.jpg, 如何将这个三个文件放在一个自定义文件中,我下次读取的时候,又应该怎么解析,分别得到这个三个文件?

解决方案 »

  1.   

    我说下我的思路啊
    文件个数
    文件名,文件长度
    文件名,文件长度
    ......
    文件名,文件长度
    文件二进制流
    例如:
    3
    a.txt,1435
    b.xml,12334
    c,jpg,234920
    234920+1435+12334个字节
    读取的时候方法:
    先读取3
    之后读取3行:文件名和长度
    最后把后面的二进制流读到byte[] bytes中,然后截断分别写入文件就ok
      

  2.   

          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 ();
            }
      

  3.   

    可能我没有表达清楚,其实我的意思是不要改变这三个文件,只是相当于做了一个zip文件一样,把这三个文件放在里面,用winRar压缩文件管理器查看的时候,可以看见这个三个独立的文件,只是外面看,这是一个叫做combination.cbn(自定义)的文件而已。:)
      

  4.   

    最简洁的做法,如微软的新Office文档格式,使用压缩包。
      

  5.   


            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();
            }
        }
      

  6.   

    要压缩的话就找找#ziplib之类的开源格式.
    懒的话.net自己带的资源文件格式也不错,而且读写都是库直接支持的.不嫌麻烦的话自己写也不错.
      

  7.   

    当然可以采取把这三个文件放入一个文件夹,然后调用ziplib压缩这个文件夹,然后更改后缀名。但是有没有别的办法呢?
    请问ChrisAK,你说的.net自带的,能稍微详细一点吗,或者链接。
      

  8.   

    我随便选择了几个文件a.jpg和b.txt,然后我把他们两个分别读取并存到了一个文件中:c.tll,然后我用一个按钮,可以把c.tll分解到一个目录下,然后该目录下就是a.jpg和b.txt两个文件了.如果你是要这个效果,我可以给你些代码参考,如果不是,就当我帮你顶了,^_^
      

  9.   


            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();
            }
      

  10.   

    先生成一个Exe文件作为母版,然后把要捆绑的文件全都放到这个Exe的后面。具体过程就是:读入一个文件到Exe的未部,写入这个文件的大小,如此循环,直到所有文件绑定完毕。运行时,这个Exe先检查自身文件的大小,如果这个Size不等于母版Exe文件自身,说明自身捆绑了文件,然后从未部根据文件的大小来释放文件,如此循环。
    这过程在C++里验证通过。我想C#应该可以实现这样的功能。另把其它文件写入到Exe的未部,并不改变Exe的文件结构,所以这个Exe文件还可以正常运行。