从C ++ ifstream转换为C#FileStream

时间:2013-10-28 21:40:38

标签: c# c++ filestream ifstream

我正在尝试通过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
…
}

2 个答案:

答案 0 :(得分:1)

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
}

答案 1 :(得分:0)

感谢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();
}

与往常一样,有人看到代码存在问题或更好的做事方式,我总是乐于接受想法。