2012-10-04 92 views
0

這個問題我有串和粘貼如下..複製從字符串到新文件

我有一個紋理文件,它不能在世界上任何紋理編輯器打開,該文件適用於例如100紋理。獲取這些紋理的唯一方法是使用十六進制編輯器(例如Hex Workshop)打開文件並找到「GBIX」字符串。當你找到一個「GBIX」字符串時,你開始從那裏複製,直到另一個GBIX的開始,你創建一個新文件,粘貼到那裏,保存爲PVR,並且你有紋理。但是,您需要這樣做100次,因爲該文件具有100個「GBIX」字符串(100個紋理)。那麼,現在,我在編程方面有一些小技巧,特別是在C#中,但我不知道如何創建一個程序,將字符串複製到字符串,然後將其保存在新文件中。

回答

0

你說你已經使用了C#。這應該給你一個關於如何在C#中做到這一點的粗略想法,雖然我沒有自己測試過它。

在你開始之前,你的文件有多大?如果它完全適合內存,讀取它的最簡單方法是使用File.ReadAllBytes,它會將整個文件讀入一個很大的字節數組中。 (如果你的文件大小是千兆字節,你將不能一次加載它,如果是這種情況,有更高級的方法來讀取文件,但我不會繼續討論這些文件。)

您可以使用File.ReadAllBytes來讀取文件Array.IndexOf以在其中搜索字節'G'和普通數組索引以檢查其他字母。當您找到它們時,您可以使用Array.Copy複製出一大塊陣列,並使用File.WriteAllBytes將其保存到文件中。

你的問題並不完全清楚文件的格式。從你的描述,我認爲這是這樣的:

HEADERBYTESblahblahblahGBIXcontentcontentcontentGBIXmorecontentGBIXyetmorecontent 

,你希望這個被丟棄:

HEADERBYTESblahblahblah 

和三個單獨的文件被創建:

GBIXcontentcontentcontent 
GBIXmorecontent 
GBIXyetmorecontent 

所以我假設在第一個「GBIX」之前可能有文本,並且您想忽略它,並且從最後一個「GBIX」到文件末尾的文本是您想要提取的適當紋理,並且沒有任何內容會出現。我還假設字符「GBIX」不會出現在其中一個紋理的中間 - 如果他們這樣做,那麼您將需要使用能夠真正理解文件格式的東西。

using System; 
using System.IO; 

public class Program 
{ 
    public static void WriteFile(int aFileIndex, byte[] sourceBytes, int firstByteIndex, int byteCount) 
    { 
     string filename = String.Format("output{0}.pvr", aFileIndex); 
     byte[] outputBytes = new byte[byteCount]; 
     Array.Copy(sourceBytes, firstByteIndex, outputBytes, 0, byteCount); 
     File.WriteAllBytes(filename, outputBytes); 
    } 

    public static void Main() 
    { 
     byte[] fileBytes = File.ReadAllBytes("inputfile"); 
     int filesOutput = 0; 
     int startIndex = -1; 
     int currentIndex = 0; 
     for (;;) 
     { 
      int nextIndex = Array.IndexOf(fileBytes, (byte)'G', currentIndex); 
      if (nextIndex == -1) 
      { 
       // There are no more ASCII 'G's in the file. 
       break; 
      } 
      if (nextIndex + 4 >= fileBytes.Length) 
      { 
       // There aren't enough characters left in the file for this 
       // to be an ASCII "GBIX" string. 
       break; 
      } 
      if (fileBytes[nextIndex+1] == (byte)'B' && 
       fileBytes[nextIndex+2] == (byte)'I' && 
       fileBytes[nextIndex+3] == (byte)'X') 
      { 
       // Found ASCII "GBIX" at nextIndex. Output the previous 
       // complete file, if there is one. 
       if (startIndex != -1) 
       { 
        Write(filesOutput, fileBytes, startIndex, nextIndex - startIndex); 
       } 
       filesOutput += 1; 
       startIndex = nextIndex; 
      } 
      currentIndex = nextIndex + 1; 
     } 
     if (startIndex != -1) 
     { 
      WriteFile(filesOutput, fileBytes, startIndex, fileBytes.Length - startIndex); 
     } 
    } 
} 
1

在C中,這將是非常簡單的:

  1. 將文件加載到內存
  2. 環槽,使用strstr()去尋找GBIX模式
  3. 對於每一個找到的模式,尋找下一個一個(或文件結尾)
  4. 對於每個找到的結尾,寫出一個新的二進制文件之間的範圍

我想在高級語言中它會更容易。 :)

你的問題是什麼?

+0

嗯,我的問題是... 1 - 如何將文件加載到C中的內存? 2 - 如何執行步驟3和4? 3 - 上帝,我真的需要在編程中真正的課程 –

0

我認爲這個代碼示例可能會對您有所幫助。它顯示瞭如何爲你解析文件。所有你需要做的就是創建一個新的文件..

using System; 
using System.IO; 
using Extensions; 
using System.Drawing; 

/* Archive Module */ 
namespace puyo_tools 
{ 
    public class Images 
    { 
     /* Image format */ 
     private ImageClass Converter = null; 
     public GraphicFormat Format = GraphicFormat.NULL; 
     private Stream Data   = null; 
     private Bitmap imageData  = null; 
     public string ImageName  = null; 
     private string FileExt  = null; 

     /* Image Object for unpacking */ 
     public Images(Stream dataStream, string dataFilename) 
     { 
      /* Set up our image information */ 
      Data = dataStream; 

      ImageInformation(ref Data, out Format, out Converter, out ImageName, out FileExt); 
     } 

     /* Unpack image */ 
     public Bitmap Unpack() 
     { 
      return Converter.Unpack(ref Data); 
     } 
     public Bitmap Unpack(Stream palette) 
     { 
      return Converter.Unpack(ref Data, palette); 
     } 

     /* Pack image */ 
     public Stream Pack() 
     { 
      return Converter.Pack(ref imageData); 
     } 

     /* Output Directory */ 
     public string OutputDirectory 
     { 
      get 
      { 
       return (ImageName == null ? null : ImageName + " Converted"); 
      } 
     } 

     /* File Extension */ 
     public string FileExtension 
     { 
      get 
      { 
       return (FileExt == null ? String.Empty : FileExt); 
      } 
     } 

     /* Get image information */ 
     private void ImageInformation(ref Stream data, out GraphicFormat format, out ImageClass converter, out string name, out string ext) 
     { 
      try 
      { 
       /* Let's check for image formats based on the 12 byte headers first */ 
       switch (data.ReadString(0x0, 12, false)) 
       { 
        case GraphicHeader.GIM: // GIM (Big Endian) 
        case GraphicHeader.MIG: // GIM (Little Endian) 
         format = GraphicFormat.GIM; 
         converter = new GIM(); 
         name  = "GIM"; 
         ext  = ".gim"; 
         return; 
       } 

       /* Ok, do special checks now */ 

       /* PVR file */ 
       if ((data.ReadString(0x0, 4) == GraphicHeader.GBIX && data.ReadString(0x10, 4) == GraphicHeader.PVRT && data.ReadByte(0x19) < 64) || 
        (data.ReadString(0x0, 4) == GraphicHeader.PVRT && data.ReadByte(0x9) < 64)) 
       { 
        format = GraphicFormat.PVR; 
        //converter = new PVR(); 
        converter = null; 
        name  = "PVR"; 
        ext  = ".pvr"; 
        return; 
       } 

       /* GVR File */ 
       if ((data.ReadString(0x0, 4) == GraphicHeader.GBIX && data.ReadString(0x10, 4) == GraphicHeader.GVRT) || 
        (data.ReadString(0x0, 4) == GraphicHeader.GCIX && data.ReadString(0x10, 4) == GraphicHeader.GVRT) || 
        (data.ReadString(0x0, 4) == GraphicHeader.GVRT)) 
       { 
        format = GraphicFormat.GVR; 
        converter = new GVR(); 
        name  = "GVR"; 
        ext  = ".gvr"; 
        return; 
       } 

       /* SVR File */ 
       if ((data.ReadString(0x0, 4) == GraphicHeader.GBIX && data.ReadString(0x10, 4) == GraphicHeader.PVRT && data.ReadByte(0x19) > 64) || 
        (data.ReadString(0x0, 4) == GraphicHeader.PVRT && data.ReadByte(0x9) > 64)) 
       { 
        format = GraphicFormat.SVR; 
        converter = new SVR(); 
        name  = "SVR"; 
        ext  = ".svr"; 
        return; 
       } 

       /* GMP File */ 
       if (data.ReadString(0x0, 8, false) == "GMP-200\x00") 
       { 
        format = GraphicFormat.GMP; 
        converter = new GMP(); 
        name  = "GMP"; 
        ext  = ".gmp"; 
        return; 
       } 

       /* Unknown or unsupported compression */ 
       throw new GraphicFormatNotSupported(); 
      } 
      catch (GraphicFormatNotSupported) 
      { 
       /* Unknown or unsupported image format */ 
       format  = GraphicFormat.NULL; 
       converter = null; 
       name  = null; 
       ext  = null; 
       return; 
      } 
      catch 
      { 
       /* An error occured. */ 
       format  = GraphicFormat.NULL; 
       converter = null; 
       name  = null; 
       ext  = null; 
       return; 
      } 
     } 

     /* Image Information */ 
     public class Information 
     { 
      public string Name = null; 
      public string Ext = null; 
      public string Filter = null; 

      public bool Unpack = false; 
      public bool Pack = false; 

      public Information(string name, bool unpack, bool pack, string ext, string filter) 
      { 
       Name = name; 
       Ext = ext; 
       Filter = filter; 

       Unpack = unpack; 
       Pack = pack; 
      } 
     } 
    } 

    /* Image Format */ 
    public enum GraphicFormat : byte 
    { 
     NULL, 
     GIM, 
     GMP, 
     GVR, 
     PVR, 
     SVR, 
    } 

    /* Image Header */ 
    public static class GraphicHeader 
    { 
     public const string 
      GBIX = "GBIX", 
      GCIX = "GCIX", 
      GIM = ".GIM1.00\x00PSP", 
      GMP = "GMP-200\x00", 
      GVRT = "GVRT", 
      MIG = "MIG.00.1PSP\x00", 
      PVRT = "PVRT"; 
    } 

    public abstract class ImageClass 
    { 
     /* Image Functions */ 
     public abstract Bitmap Unpack(ref Stream data); // Unpack image 
     public abstract Stream Pack(ref Bitmap data);  // Pack Image 
     public abstract bool Check(ref Stream data);  // Check Image 
     public abstract Images.Information Information(); // Image Information 
     public virtual Bitmap Unpack(ref Stream data, Stream palette) // Unpack image (with external palette file) 
     { 
      return null; 
     } 
    } 
} 
1

你能在C. 然後程序只是下面的事情

1.open the file using `fopen()` in binary mode. 
2.use a loop upto the end of file and search for the string what you want (strstr() to look for the GBIX pattern)-copied from unwind 
3.Then after finding each pattern get the position of the file pointer using ftell() and store it to a array of 100 integer(as 100 of texture you have). 
4.Then go to the first byte of file by using fseek(). 
5.Now you can use your array to find the location and read the whole data up to the next array element (do it in a loop upto 100 times). 
6.then store this data or write it to another file(open a file in append mode and write there). 

我覺得有點棘手,但使用這種算法和搜索對於來自互聯網的代碼,你一定能做到這一點。

相關問題