从 C++ ifstream 转换为 C# FileStream

Converting from C++ ifstream to C# FileStream

本文关键字:FileStream 转换 C++ ifstream      更新时间:2023-10-16

我正在尝试通过DirectX教程学习SharpDX。我在我正在使用的C++项目中有以下代码行:

std::ifstream fin("Models/skull.txt");
if(!fin)
{
    MessageBox(0, L"Models/skull.txt not found.", 0, 0);
    return;
}
UINT vcount = 0;
UINT tcount = 0;
std::string ignore;
fin >> ignore >> vcount;
fin >> ignore >> tcount;
fin >> ignore >> ignore >> ignore >> ignore;
float nx, ny, nz;
XMFLOAT4 black(0.0f, 0.0f, 0.0f, 1.0f);
std::vector<Vertex> vertices(vcount);
for(UINT i = 0; i < vcount; ++i)
{
    fin >> vertices[i].Pos.x >> vertices[i].Pos.y >> vertices[i].Pos.z;
    vertices[i].Color = black;
    // Normal not used in this demo.
    fin >> nx >> ny >> nz;
}
fin >> ignore;
fin >> ignore;
fin >> ignore;
mSkullIndexCount = 3*tcount;
std::vector<UINT> indices(mSkullIndexCount);
for(UINT i = 0; i < tcount; ++i)
{
    fin >> indices[i*3+0] >> indices[i*3+1] >> indices[i*3+2];
}
fin.close();

我想知道如何将其隐蔽到 C#。 我 99% 确定我需要使用System.IO.FileStream但我不确定所有C++的东西是如何工作的。 真正让我搞砸的是fin >> ignore >> vcount;如果有人可以向我解释如何在 C# 中做同样的事情,我可能会从那里弄清楚。

根据要求,文本文件类似于以下内容:

VertexCount: 31076
TriangleCount: 60339
VertexList (pos, normal)
{
0.592978 1.92413 -2.62486 0.572276 0.816877 0.0721907
0.571224 1.94331 -2.66948 0.572276 0.816877 0.0721907
0.609047 1.90942 -2.58578 0.572276 0.816877 0.0721907
…
}
TriangleList
{
0 1 2
3 4 5
6 7 8
…
}
ignore

声明为std::string。 您正在查看的代码的原始作者似乎不知道std::istream::ignore函数,并且正在使用局部变量来读取他们只是丢弃的文件元素(也就是说,他并不关心)。 所以像这样的行:

fin >> ignore >> vcount;
正在读取字符串

元素(基本上直到第一个空格)并将其转储到他忽略的本地字符串中,然后读取vcount值(他将其存储为unsigned int)。

如果要将其移植到 C#,您可以做同样的事情(读取文件的某些部分并简单地丢弃它们),这将是一个相当直接的端口。

举个例子(未测试):

using (FileStream file = new FileStream("File.txt", FileMode.Open))
using (StreamReader reader = new StreamReader(file))
{
    // with your sample, this will read "VertexCount: 31076"
    string line = reader.ReadLine();
    string sVCount = line.Substring(line.IndexOf(": ") + 2);
    uint vcount = int.Parse(sVCount);
    // ... read of your code
}
多亏了

Zac Howland的回答,我才能让一切正常。对于其他试图将Frank Luna的书从DirectX转换为SharpDX的人,我希望这有所帮助。 这是我最终做的事情:

private void _buildGeometryBuffers()
{
    System.IO.FileStream fs = new System.IO.FileStream(@"Chapter6/Content/skull.txt", System.IO.FileMode.Open);
    int vcount = 0;
    int tcount = 0;
    //string ignore = string.Empty; // this is not needed for my C# version
    using (System.IO.StreamReader reader = new System.IO.StreamReader(fs))
    {
        // Get the vertice count
        string currentLine = reader.ReadLine();
        string extractedLine = currentLine.Substring(currentLine.IndexOf(" ") + 1);
        vcount = int.Parse(extractedLine);
        // Get the indice count
        currentLine = reader.ReadLine();
        extractedLine = currentLine.Substring(currentLine.IndexOf(" ") + 1);
        tcount = int.Parse(extractedLine);
        // Create vertex buffer
        // Skip over the first 2 lines (these are not the lines we are looking for)
        currentLine = reader.ReadLine();
        currentLine = reader.ReadLine();
        string[] positions = new string[6];
        List<VertexPosCol> vertices = new List<VertexPosCol>(vcount);
        for (int i = 0; i < vcount; ++i)
        {
            currentLine = reader.ReadLine();
            extractedLine = currentLine.Substring(currentLine.IndexOf("t") + 1);
            positions = extractedLine.Split(' ');
            // We only use the first 3, the last 3 are normals which are not used.
            vertices.Add(new VertexPosCol(
                new Vector3(float.Parse(positions[0]), float.Parse(positions[1]), float.Parse(positions[2])),
                Color.Black)
            );
        }
        BufferDescription vbd = new BufferDescription();
        vbd.Usage = ResourceUsage.Immutable;
        vbd.SizeInBytes = Utilities.SizeOf<VertexPosCol>() * vcount;
        vbd.BindFlags = BindFlags.VertexBuffer;
        vbd.StructureByteStride = 0;
        _vBuffer = Buffer.Create(d3dDevice, vertices.ToArray(), vbd);
        // Create the index buffer
        // Skip over the next 3 lines (these are not the lines we are looking for)
        currentLine = reader.ReadLine();
        currentLine = reader.ReadLine();
        currentLine = reader.ReadLine();
        string[] indexes = new string[6];
        _meshIndexCount = 3 * tcount;
        List<int> indices = new List<int>(_meshIndexCount);
        for (int i = 0; i < tcount; ++i)
        {
            currentLine = reader.ReadLine();
            extractedLine = currentLine.Substring(currentLine.IndexOf("t") + 1);
            indexes = extractedLine.Split(' ');
            indices.Add(int.Parse(indexes[0]));
            indices.Add(int.Parse(indexes[1]));
            indices.Add(int.Parse(indexes[2]));
        }
        BufferDescription ibd = new BufferDescription();
        ibd.Usage = ResourceUsage.Immutable;
        ibd.SizeInBytes = Utilities.SizeOf<int>() * _meshIndexCount;
        ibd.BindFlags = BindFlags.IndexBuffer;
        _iBuffer = Buffer.Create(d3dDevice, indices.ToArray(), ibd);
    }
    fs.Close();
}

与往常一样,有人看到代码有问题或更好的做事方式,我总是对想法持开放态度。