从一个字符串复制到另一个字符串并粘贴到新文件中

Copying from string to string and pasting in new file

本文关键字:字符串 新文件 文件 串并 字符 一个 复制 另一个      更新时间:2023-10-16

我的问题如下。。

我有一个纹理文件,它不能用世界上任何纹理编辑器打开,该文件包含例如100个纹理。获取这些纹理的唯一方法是使用Hex Editor(例如Hex Workshop)打开文件并找到"GBIX"字符串。当你找到一个"GBIX"字符串时,你开始从那里复制,直到另一个GBIX开始,你创建一个新文件,粘贴到那里,保存为PVR,你就有了纹理。但是,您需要这样做100次,因为文件有100个"GBIX"字符串(100个纹理)。好吧,现在,我在编程方面有一些小技巧,特别是在C#中,但我不知道如何创建一个程序,从一个字符串复制到另一个字符串,然后将其保存在一个新文件中。

在C中,这将是非常琐碎的:

  1. 将文件加载到内存中
  2. 循环槽,使用strstr()查找GBIX模式
  3. 对于每个找到的模式,查找下一个(或文件末尾)
  4. 对于每个找到的末端,将之间的范围写入一个新的二进制文件

我想在高级语言中会更容易。:)

你的问题是什么?

你能用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).

我觉得有点棘手,但使用这个算法并从互联网上搜索代码,你肯定能做到这一点。

您说您使用了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);
}
}
}

我认为这个代码示例可能会对您有所帮助。它展示了如何为您解析文件。你所需要做的就是创建一个新文件。。

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-200x00")
{
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.00x00PSP",
GMP  = "GMP-200x00",
GVRT = "GVRT",
MIG  = "MIG.00.1PSPx00",
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;
}
}
}