マジックナンバーを使用してコンテンツの開始をマークする単純な自己解凍型アーカイブを作成しています。今のところ、それはテキストファイルです:
MAGICNUMBER ....テキストファイルの内容
次に、実行可能ファイルの末尾にテキスト ファイルをコピーします。
programm.exe/b+textfile.txt/b sfx.exe をコピーします。
次のコードを使用して、2 番目に出現するマジック ナンバー (最初のものは明らかにハードコードされた定数) を見つけようとしています。
string my_filename = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
StreamReader file = new StreamReader(my_filename);
const int block_size = 1024;
const string magic = "MAGICNUMBER";
char[] buffer = new Char[block_size];
Int64 count = 0;
Int64 glob_pos = 0;
bool flag = false;
while (file.ReadBlock(buffer, 0, block_size) > 0)
{
var rel_pos = buffer.ToString().IndexOf(magic);
if ((rel_pos > -1) & (!flag))
{
flag = true;
continue;
}
if ((rel_pos > -1) & (flag == true))
{
glob_pos = block_size * count + rel_pos;
break;
}
count++;
}
using (FileStream fs = new FileStream(my_filename, FileMode.Open, FileAccess.Read))
{
byte[] b = new byte[fs.Length - glob_pos];
fs.Seek(glob_pos, SeekOrigin.Begin);
fs.Read(b, 0, (int)(fs.Length - glob_pos));
File.WriteAllBytes("c:/output.txt", b);
しかし、何らかの理由で、最後の数キロバイトではなく、ファイルのほぼ全体をコピーしています。似たようなものの while ループで魔法の定数をインライン化する、コンパイラの最適化のためですか?
自己解凍アーカイブを正しく行うにはどうすればよいですか?
コンパイラがマジック定数の乗算回数をインライン化する問題を回避するために、ファイルを逆方向に読み取る必要があると推測しました。したがって、次のようにコードを変更しました。
string my_filename = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
StreamReader file = new StreamReader(my_filename);
const int block_size = 1024;
const string magic = "MAGIC";
char[] buffer = new Char[block_size];
Int64 count = 0;
Int64 glob_pos = 0;
while (file.ReadBlock(buffer, 0, block_size) > 0)
{
var rel_pos = buffer.ToString().IndexOf(magic);
if (rel_pos > -1)
{
glob_pos = block_size * count + rel_pos;
}
count++;
}
using (FileStream fs = new FileStream(my_filename, FileMode.Open, FileAccess.Read))
{
byte[] b = new byte[fs.Length - glob_pos];
fs.Seek(glob_pos, SeekOrigin.Begin);
fs.Read(b, 0, (int)(fs.Length - glob_pos));
File.WriteAllBytes("c:/output.txt", b);
}
そのため、すべてのファイルを 1 回スキャンしたところ、マジック ナンバーの最後の出現箇所であることがわかり、ここから最後までコピーしました。この手順で作成されたファイルは以前の試行よりも小さく見えますが、「自己解凍型」アーカイブに添付したファイルと同じではありません。なんで?
私の推測では、バイナリから文字列への変換が使用されているため、添付ファイルの先頭の位置計算が間違っていると思われます。もしそうなら、どのように位置計算を修正して正しくする必要がありますか?
また、マジックナンバーを選択して実際のファイル、たとえばpdfを操作するにはどうすればよいですか? PDF を簡単に変更して、定義済みのマジック ナンバーを含めることはできません。