バイナリファイルからレジストリを読み込む

バイナリファイルレジストリに書き込んだ後のプログラム:

StringBuilder name0 = new StringBuilder(15);
int stock0, safe0;
double cost0;

レジストリの位置に基づいてIDを与えることによって、1つのレジストリのデータを読み取る必要があります。

レジストリは20バイトなので、各レジストリの位置は次のようになります。

pos = (id-1) * 20;

右?

問題は、 StringBuilder には、正確に15文字ではなく、毎回書く名前の長さが格納され、必要なデータを読み込む代わりにゴミが読み込まれるということです。常に正確なサイズを持つ文字列を宣言する方法がないので、データを正しく読み取ることができますか?

コード:

public static void Main(string[] args)
{
    Console.WriteLine("Give file name: ");
    string f = Console.ReadLine();

    StringBuilder name0 = new StringBuilder(15);
    bool criterion = true;
    int stock0, safe0;
    double cost0;
    long id, pos;

    try
    {
        FileStream fs = File.Open(f, FileMode.Create, FileAccess.ReadWrite);
        BinaryWriter writer = new BinaryWriter(fs);
        BinaryReader reader = new BinaryReader(fs);

        while (criterion != false)
        {
            Console.WriteLine("Give name (10 char) or STOP for end");
            name0.Insert(0, Console.ReadLine());

            if ((name0.ToString()).Equals("STOP"))
                criterion = false;
            else
            {
                Console.WriteLine("Stock : ");
                stock0 = Int32.Parse(Console.ReadLine());

                Console.WriteLine("Safe: ");
                safe0 = Int32.Parse(Console.ReadLine());

                Console.WriteLine("Cost: ");
                cost0 = double.Parse(Console.ReadLine());

                writer.Write(name0.ToString());
                writer.Write(stock0);
                writer.Write(safe0);
                writer.Write(cost0);
            }//else

            name0.Remove(0, name0.Length);

        } //while

        Console.WriteLine(" Give ID: ");
        id = long.Parse(Console.ReadLine());
        pos = (id - 1) * 20; //20 = megethos eggrafis(2 int+ 1db + 16chars)

        if ((pos < fs.Length) && (id != 0))
        {
            fs.Seek(pos, SeekOrigin.Begin);
            name0.Insert(0, reader.ReadChars(name0.Length));
            Console.WriteLine("Name: {0}", name0);
            stock0 = reader.ReadInt32();
            Console.WriteLine("\nStock: {0}", stock0);
            safe0 = reader.ReadInt32();
            Console.WriteLine("\nSafe: {0}", safe0);
            cost0 = reader.ReadDouble();
            Console.WriteLine("\nCost: {0}", cost0);
            name0.Length = 0;
        }

        fs.Close();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}
0
あなたの質問はほとんど理解できません。あなたがそれを達成しようとしているのではなく、あなたが達成しようとしていることを説明してみませんか?より良い方法を提案できるかもしれません。
追加された 著者 spender,
私はそれから20バイトを得る方法は見当たりません
追加された 著者 Mark Peters,
16バイト4バイト?どのような文字セットですか?
追加された 著者 Zruty,
私は各変数の長さを8バイト(2整数)+ 8バイト(1ダブル)+ 4バイト(16文字)= 20バイトと数えましたか?どのように私は各レコードの位置を得ることができますか?何か間違っているのですか?
追加された 著者 BreJohn,
ユニコード文字はそれぞれ2ビットではなく2バイトです(私の悪い!)。私は私の大学からUnicodeの文字が2ビットであると言うひどい本を持っています...
追加された 著者 BreJohn,

1 答え

char [15] として宣言しない限り、C#で固定長文字列を宣言することはできません。しかし、値を書いているときは手作業でスペースを埋め、読み込みのときはスペースをつけることができます:

// writing
writer.Write(name0.ToString().PadRight(15));

//reading
name0.Insert(0, reader.ReadChars(15));
name0 = new StringBuilder(name0.ToString().Trim());
0
追加された
私は今コードを修正しました。パフォーマンスに関して本当に心配している場合を除き、このコンテキストで StringBuilder を使用するのが良いかどうかはわかりません。
追加された 著者 Zruty,
実際には、 capacity または length の代わりに reader.ReadChars(15)を実行する必要があります。奇妙なデータは最初は - おそらくUTFファイルのヘッダですか?
追加された 著者 Zruty,
それは素晴らしいですが、文字列ビルダにはTrim()メソッドがありません: - /
追加された 著者 BreJohn,
Read.ReadChars(name0.Length)の代わりにreader.ReadChars(name0.capacity)を書くと(最初の文字は*のような奇妙なものですが)他の値はすべて間違っていれば、名前は正しく読み込まれます。バイナリファイルから整数を読み込む際に何か問題がありますか?
追加された 著者 BreJohn,