簡體   English   中英

如何在C#中以有效方式將文本文件轉換為二進制文件

[英]How to convert text files to binary in an efficient way in C#

我檢查了幾種將文本文件轉換為二進制文件的方法,並在此處找到了一些答案。 但是,由於Unity .NET的兼容性,他們中的大多數使我感到困惑,而且我對如何將文本轉換為二進制的結構也感到困惑。

我有一個文本文件(導出的點雲),該文件保存3D空間中點的位置和顏色信息,如下所示:

XYZ colorvalues -0.680891 -90.6809 0 204 204 204 255

我正在閱讀以下內容,以便在運行時使用如下腳本創建網格:

 string[] buffer;

    for (int i = 0; i < Area.nPoints; i++)
    {
        buffer = sr.ReadLine().Split();

        Area.AddPoint(new Vector3(float.Parse(buffer[0]), 
        float.Parse(buffer[1]), float.Parse(buffer[2])));
    }

這行得通,但是由於我讀取行並拆分了它們,這非常慢,並且我的文本文件中大約有7500萬行(點)。 我發現我可以將其轉換為二進制文件,並且讀取速度會更快,而且速度也快得多。 但是,現在轉換為二進制部分非常慢,我想問一下我的轉換方式。

void WriteValues()
{
    string[] buffer;

    for (int i = 0; i < numPoints; i++)
    {
        buffer = sr.ReadLine().Split();
        for (int j = 0; i < 3; i++)
        {
            wr.Write(float.Parse(buffer[j]));
        }           
    }        
    wr.Close();
}

然后,我使用BinaryReader.ReadSingle()進行了讀取,但是這比直接從文本中讀取要花費更多的時間,因為我再次讀取了該行並將其拆分。

我的問題是我可以說讓接下來的1000行緩沖然后寫入而不是讀取每一行嗎? 會有所作為嗎? 如果是這樣,我如何每1000行使用一次stream。

另外,當我將一行轉換為二進制時,如何在不分割字符串的情況下讀取行中的每個浮點數? 在此先感謝您的幫助!

我正在嘗試使用增強現實技術來可視化手機中的點雲。 因此,我想進行掃描,將點雲導出,將其導入Unity並使用這些點創建網格,而無需進行三角剖分,但是使用我的初始方法,導入它需要15-18分鍾。 轉換為二進制文件后,只需不到3分鍾的時間就可以了。 但是,這次轉換為二進制文件需要很多時間:)

因此,一種合理的快速讀取方法是使用緩沖的文件流。 如果不進行浮點解析,則在我的計算機上讀取將花費14 ish秒。...進行浮點解析需要74秒ish(我只是總結一下,因為我沒有團結精神)

var sw = new Stopwatch();
sw.Start();
double sum = 0;
var fs = new FileStream("demo.txt", FileMode.Open, FileAccess.Read);
using (var bs = new BufferedStream(fs))
using (var r = new StreamReader(bs))
{
    r.ReadLine();
    while (!r.EndOfStream)
    {
        var l = r.ReadLine();
        var split = l.Split();
        var x = float.Parse(split[0]);
        var y = float.Parse(split[1]);
        var z=float.Parse(split[2]);
        sum += x + y + z;
    }
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds / 1000M);
Console.WriteLine(sum);

出於興趣,我還更改了代碼以將數據寫成浮點流(在三胞胎中)

閱讀與

var sw = new Stopwatch();
sw.Start();
double sum = 0;
var fs = new FileStream("demo.bin", FileMode.Open, FileAccess.Read);
using (var bs = new BufferedStream(fs))
using (var r = new BinaryReader(bs))
{
    for (int i = 0; i < 75000000; i++)
    {
        var x = r.ReadSingle();
        var y = r.ReadSingle();
        var z=r.ReadSingle();
        sum += x + y + z;
    }
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds / 1000M);
Console.WriteLine(sum);

大約需要9秒

僅出於完整性考慮,我使用以下代碼生成演示文件。

   var random = new Random();
    File.WriteAllText("demo.txt", "X         Y        Z colorvalues\r\n");
    using (var fs = new FileStream("demo.bin", FileMode.Create, FileAccess.Write, FileShare.None))
    using (var bw = new BinaryWriter(fs))
    using (var writer = File.AppendText("demo.txt"))
    {
        for (int i = 0; i < 75000000; i++)
        {
            var x = (float) random.NextDouble() * 200;
            var y = (float) random.NextDouble() * 200;
            var z = (float) random.NextDouble() * 200;
            var c = Enumerable.Range(0, 4).Select(n => random.Next(0, 255)).ToArray();
            writer.WriteLine($"{x} {y} {z} {c[0]} {c[1]} {c[2]} {c[3]}");
            bw.Write(x);
            bw.Write(y);
            bw.Write(z);
        }
}

那可能是個愚蠢的問題,但是為什么不掃描並直接保存到二進制或.ply文件中呢? 甚至掃描並保存到網格或某些體素化網格中

您還可以查找項目中使用的方法,尤其是PlyImporter.cs

如果讀取速度很慢,則讀取,寫入其他文件格式然后從該文件讀回的速度甚至會更慢。 您只是向已經很慢的事物添加了更多操作...也許您應該看看如何更改從文本文件讀取內容的方式。

如果您不熟悉如何使用內置庫在C#中完成序列化/反序列化,則應先閱讀以下內容: https : //docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/概念/序列化/

以下是顯示如何實現二進制序列化的鏈接: https : //docs.microsoft.com/zh-cn/dotnet/api/system.runtime.serialization.formatters.binary.binaryformatter?view=netframework-4.7.2

但是,如果您不寫初始文件,則只需要編寫一個自定義反序列化器(本質上就是您要做的-不實現相關的.NET模式)。 也許嘗試使用BufferedStream ,看看是否有幫助,即:

using (FileStream fs = File.Open(fileName, ..... ))
using (BufferedStream bs = new BufferedStream(fs))
using (StreamReader sr = new StreamReader(bs))
{
        string s;
        while ((s = sr.ReadLine()) != null)
        {
            //your code   
        }
}

同樣值得一看的是這個可以幫助您完成此任務的庫: FileHelpers-查看以下示例: https : //www.filehelpers.net/example/QuickStart/ReadFileDelimited/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM