前些天发表了一个帖子  由于没阐述清楚 引发了众多朋友的口水,对此道歉!现在我重新描述一下!我现在要实现的是将所有影像格式的文件或者所有图片格式的文件,通过我的程序,能够压缩到一起!这个程序有如下要求!
1. 有解析功能,能够将我合成后的这个文件解析显示出来
2. 假如是将10个文件压缩在一起了,可以任意打开其中的一个或多个文件。比如说打开第4个和第7个  就是将4和7组合起   来!
3. 这些文件的组合方式就如同WORD文档里插入了几张图片那样, 不交叉的一个跟着一个排列开来!不需要按坐标或者其他标志重叠!希望大家能给点思路!对于新格式的定义  以及 解析  给点想法  咱一窍不通

解决方案 »

  1.   

    做一个记录的文件保存在新压缩的文件内,这个文件主要保存有被压缩的文件的文件名、原始大小、压缩后的起始位置、文件压缩前的格式等。
    因为这些信息在压缩格式下浏览以及解压缩的时候都有用的。
    至于压缩算法,网上或者.net类库里面有现成的,直接拿来用就行了。
      

  2.   

    上次给你写的这段不符合要求?
    1.任何文件要加进去都AppendFile一下,通过纯字节方式自动打包进c:\A.ALL,
    2.要解析出哪个文件就ExtractFile出哪个,还能另存
    3.不是很理解你说的解出第4个和第7个,又说组合起来是什么意思,反正合并和解析都写了,基本功能算可以了吧4.如果你说的是多张不同格式图片合并成一张图片,那也许可以试试把图片都image.save成bitmap,然后都g.draw到一个大的新bitmap里去using System;
    using System.Collections.Generic;
    using System.Text;
    using System.IO;namespace ConsoleApplication22
    {
        class Program
        {
            const String ObjectFileName = @"c:\A.ALL";        static void Main(string[] args)
            {
                File.Delete(ObjectFileName);
                AppendFile(@"c:\windows\system.ini");
                AppendFile(@"c:\windows\regedit.exe");
                Console.WriteLine("合并完成");
                ExtractFile(@"system.ini", @"c:\system2.ini");
                ExtractFile(@"regedit.exe", @"c:\regedit2.exe");
                Console.WriteLine("分解完成");
                Console.Read();        }        static void AppendFile(String AppendFileName)
            {
                FileStream ObjectFS = null;
                FileStream FS = null;
                try
                {
                    ObjectFS = new FileStream(ObjectFileName, FileMode.Append);
                    FS = new FileStream(AppendFileName, FileMode.Open);
                    ObjectFS.Seek(0, SeekOrigin.End);
                    char[] Length = new char[10];
                    FS.Length.ToString().CopyTo(0, Length, 0, FS.Length.ToString().Length);
                    foreach (char C in Length)
                        ObjectFS.WriteByte((byte)C);
                    char[] Name = new char[256];
                    Path.GetFileName(AppendFileName).CopyTo(0, Name, 0, Path.GetFileName(AppendFileName).Length);
                    foreach (char C in Name)
                        ObjectFS.WriteByte((byte)C);
                    FS.Seek(0, SeekOrigin.Begin);
                    while (FS.Position < FS.Length)
                        ObjectFS.WriteByte((byte)FS.ReadByte());
                }
                finally
                {
                    if (FS != null)
                        FS.Close();
                    if (ObjectFS != null)
                        ObjectFS.Close();
                }
            }        static void ExtractFile(String ExtractFileName, String SaveToFileName)
            {
                FileStream ObjectFS = null;
                FileStream FS = null;
                try
                {
                    ObjectFS = new FileStream(ObjectFileName, FileMode.OpenOrCreate);
                    ObjectFS.Seek(0, SeekOrigin.Begin);
                    byte[] FileLength = new byte[10];
                    ObjectFS.Read(FileLength, 0, 10);
                    String LengthString = String.Empty;
                    foreach (byte B in FileLength)
                        LengthString += (char)B;
                    int Length = int.Parse(LengthString);
                    byte[] FileName = new byte[256];
                    ObjectFS.Read(FileName, 0, 256);
                    String Name = String.Empty;
                    foreach (byte B in FileName)
                        if ((char)B != '\0')
                            Name += (char)B;
                        else
                            break;
                    while (Name != ExtractFileName)
                    {
                        ObjectFS.Seek(Length, SeekOrigin.Current);
                        int x = ObjectFS.Read(FileLength, 0, 10);
                        LengthString = String.Empty;
                        foreach (byte B in FileLength)
                            LengthString += (char)B;
                        Length = int.Parse(LengthString.Trim());
                        ObjectFS.Read(FileName, 0, 256);
                        Name = String.Empty;
                        foreach (byte B in FileName)
                            if ((char)B != '\0')
                                Name += (char)B;
                            else
                                break;
                    }
                    if (ObjectFS.Position < ObjectFS.Length)
                    {
                        FS = new FileStream(SaveToFileName, FileMode.Create);
                        for (int i = 0; i < Length; i++)
                            FS.WriteByte((byte)ObjectFS.ReadByte());
                    }
                }
                finally
                {
                    if (FS != null)
                        FS.Close();
                    if (ObjectFS != null)
                        ObjectFS.Close();
                }
            }
        }
    }
      

  3.   

    谢谢你的好意!!!其实不是这么简单的  如果真是这样的话  我就去网上下了!这个东西要涉及到各市重新编码的问题  根本就不只是图片这种格式一种 我只是举例说了一下!比如GIF和TIF的合并呢?这个程序一定要重新定义文件头,然后制定出一套新的编码格式,并且能够解析当前合并出来的文件!你说不明白第4和第7那个意思!  其实每个文件的文件头都会有内部文件编码的地址  可能是RVA地址吧  这样的话就相当于在文件头中有一个索引,咱不是将10个文件合并了吗?这十个文件在这个新文件中都有自己的地址  我可以随便把八门任何两个文件提取出来再临时组合一个新的文件出来
      

  4.   

    还是上次那个问题啊实际上次已经说了你要的就是能同时保存底图和图层的格式,我记得上个帖子就有人贴过gis方面mapX的资料,你可以参考如果你用photoshop那么你可能会知道psd格式,实际psd格式也是底图和图层
    下面是一个psd格式的C#操作类
    http://tech.e800.com.cn/articles/2009/525/1243217133388_1.html
    ps:如果你觉得psd或者mapx格式理解起来有困难或没那么多时间去理解,那么就请自己设计格式
    ls的代码实际就是一个自己设计的格式,但是少了一部分和图层分布的信息呵呵,如果你操作过photoshop或flash那么你可能会更能理解我说的,
    按lz的描述,你想设计的东西应该是和flash的图层和元件库很类似吧如果是我,如果不是为通用性的话,我可能直接设计一个可序列化的类就成,当然还要设计一个能对这个类进行显示操作的控件。
    class 图层信息
    {
       image 图形元素;
       point 图形位置;
       bool 是否显示;
    }class 图形包
    {
      image 底图;
      image[] 图层的集合;
    }
    上面是一个基本思路,如果你看明白了自己去扩展他把
    或者干脆啥不不理,直接设计一个xml文件,图形数据直接 base64后,然后cdate入xml节点
      

  5.   

    5楼 能不能帮我把你这个程序改成WinForm的 再加上注释啊。
      

  6.   

    很有难度的问题啊,每种数据格式的头文件都不同,这就需要很多种提取数据的方法了,比如avi和jpg要合起来就不容易,如果是同格式的要简单的多。
      

  7.   


    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.IO;namespace ConsoleApplication22
    {
        class Program
        {
            const String ObjectFileName = @"c:\A.ALL"; // 最终合并文件名        static void Main(string[] args)
            {
                File.Delete(ObjectFileName);// 最终合并文件如果存在,则删除,重新创建
                AppendFile(@"c:\windows\system.ini"); // 添加第一个文件到最终合并文件
                AppendFile(@"c:\windows\regedit.exe"); // 添加第二个文件到最终合并文件
                Console.WriteLine("合并完成");
                ExtractFile(@"system.ini", @"c:\system2.ini"); // 分解当初的合并文件"system.ini"从最终合并文件并另存为c:\system2.ini
                ExtractFile(@"regedit.exe", @"c:\regedit2.exe"); // 分解当初的合并文件"regedit.exe"从最终合并文件并另存为c:\regedit2.exe
                Console.WriteLine("分解完成");
                Console.Read();        }        static void AppendFile(String AppendFileName)
            {
                FileStream ObjectFS = null; // 要新建的最终合并文件的文件流
                FileStream FS = null; // 要合并的文件的文件流
                try
                {
                    ObjectFS = new FileStream(ObjectFileName, FileMode.Append);  // 新建最终合并文件
                    FS = new FileStream(AppendFileName, FileMode.Open); // 打开要合并的文件
                    ObjectFS.Seek(0, SeekOrigin.End); // 最终合并文件定位到最后准备添加 ,这句多余,我忘删了,本来是打算可以续写,后来觉得没必要
                    char[] Length = new char[10];
                    FS.Length.ToString().CopyTo(0, Length, 0, FS.Length.ToString().Length);  
                    foreach (char C in Length)
                        ObjectFS.WriteByte((byte)C); // 要合并的文件的长度值转换成字节存入
                    char[] Name = new char[256];
                    Path.GetFileName(AppendFileName).CopyTo(0, Name, 0, Path.GetFileName(AppendFileName).Length);
                    foreach (char C in Name)
                        ObjectFS.WriteByte((byte)C); // 要合并的文件的名称转换成字节存入
                    FS.Seek(0, SeekOrigin.Begin);
                    while (FS.Position < FS.Length)
                        ObjectFS.WriteByte((byte)FS.ReadByte()); // 要合并的文件的具体内容转换成字节存入
                }
                finally
                {
                    if (FS != null)
                        FS.Close();
                    if (ObjectFS != null)
                        ObjectFS.Close();
                }
            }        static void ExtractFile(String ExtractFileName, String SaveToFileName)
            {
                FileStream ObjectFS = null; // 要分解的最终合并文件的文件流
                FileStream FS = null; // 要另存的文件的文件流
                try
                {
                    ObjectFS = new FileStream(ObjectFileName, FileMode.OpenOrCreate); // 打开要分解的最终合并文件
                    ObjectFS.Seek(0, SeekOrigin.Begin); // 要分解的最终合并文件定位到开始
                    byte[] FileLength = new byte[10]; 
                    ObjectFS.Read(FileLength, 0, 10); // 读出文件长度值
                    String LengthString = String.Empty;
                    foreach (byte B in FileLength)
                        LengthString += (char)B;
                    int Length = int.Parse(LengthString);
                    byte[] FileName = new byte[256];
                    ObjectFS.Read(FileName, 0, 256); // 读出文件名
                    String Name = String.Empty;
                    foreach (byte B in FileName)
                        if ((char)B != '\0')
                            Name += (char)B;
                        else
                            break;
                    while (Name != ExtractFileName)  // 如果这个文件不是要分解的,继续往下搜索
                    {
                        ObjectFS.Seek(Length, SeekOrigin.Current); //要分解的最终合并文件定位到当前+文件具体内容长度,就是跳过这个文件 
                        int x = ObjectFS.Read(FileLength, 0, 10); // 读出文件长度值
                        LengthString = String.Empty;
                        foreach (byte B in FileLength)
                            LengthString += (char)B;
                        Length = int.Parse(LengthString.Trim());
                        ObjectFS.Read(FileName, 0, 256); // 读出文件名
                        Name = String.Empty;
                        foreach (byte B in FileName)
                            if ((char)B != '\0')
                                Name += (char)B;
                            else
                                break;
                    }
                    if (ObjectFS.Position < ObjectFS.Length) // 如果没有到要分解的最终合并文件尾,说明有内容,文件没被破坏,就另存
                    {
                        FS = new FileStream(SaveToFileName, FileMode.Create);
                        for (int i = 0; i < Length; i++)
                            FS.WriteByte((byte)ObjectFS.ReadByte()); // 另存
                    }
                }
                finally
                {
                    if (FS != null)
                        FS.Close();
                    if (ObjectFS != null)
                        ObjectFS.Close();
                }
            }
        }
    }
      

  8.   

    if (ObjectFS.Position < ObjectFS.Length) 还有一个功能就是如果要具有该分解的文件名的文件不存在则跳过