在C#中保存/加载巨型布尔数组到磁盘?
我有10亿个体素的体素文件,每个体素都是真/假的,并保存在一个1D布尔数组中 什么是将其复制到磁盘的好方法,例如作为字节/0100010101 ASCII文件,在那里我可以快速高效地将文件读回内存 目前,我可以使用以下方法将文件写入磁盘:在C#中保存/加载巨型布尔数组到磁盘?,c#,.net,C#,.net,我有10亿个体素的体素文件,每个体素都是真/假的,并保存在一个1D布尔数组中 什么是将其复制到磁盘的好方法,例如作为字节/0100010101 ASCII文件,在那里我可以快速高效地将文件读回内存 目前,我可以使用以下方法将文件写入磁盘: savePath = System.IO.Directory.GetParent(Application.dataPath).ToString()+ "/Saved_Files" ; var sw : System.IO.StreamWriter; 我不
savePath = System.IO.Directory.GetParent(Application.dataPath).ToString()+ "/Saved_Files" ;
var sw : System.IO.StreamWriter;
我不知道读写1-2gb文件的最佳方式
这就是我现在写的:
function saveBW(){
//var SW2 : System.IO.StreamWriter;
var timeString = DateTime.Now.ToString("HH-mm");
var fileNameFromFolder= Path.GetFileNameWithoutExtension(QPath[QDone]);
fileNameFromFolder = stripTrailingSlash(fileNameFromFolder);
PLYname = "MK5_aliased_" + fileNameFromFolder + "_"+ timeString + ".Bo0L" ;
var str ="";
var SW2 = new System.IO.StreamWriter(savePath + "/" + PLYname);
for( var tr = 0 ; tr < mesher.supernormous.Length ; tr++ )
{
str += mesher.supernormous ? 1 : 0;
if(tr%255==0)SW2.Write(str);
}
SW2.Write(str);
SW2.Flush();
SW2.Close();
}
函数saveBW(){
//var SW2:System.IO.StreamWriter;
var timeString=DateTime.Now.ToString(“HH-mm”);
var fileNameFromFolder=Path.GetFileNameWithoutExtension(QPath[QDone]);
fileNameFromFolder=stripTrailingSlash(fileNameFromFolder);
PLYname=“MK5\u别名”+fileNameFromFolder+“\u”+timeString+”.Bo0L”;
var str=“”;
var SW2=新的System.IO.StreamWriter(保存路径+“/”+PLYname);
对于(var tr=0;tr布尔值在.NET中没有一点大小,因此它们不是您想要的数据类型的良好存储。相反,请使用
位数组
——它仍然提供您所需的所有操作(读取一个位值,写入一个位值),并允许您在字节[]
中加载和存储整个数组(每个字节最多八位)。这使得持久性非常容易:
var data = new BitArray(File.ReadAllBytes("MyFile.bin"));
当然,这到底有多高效取决于分析。可能您不想加载数据,除非实际需要,所以某种分页解决方案可能更好;但这超出了您的问题范围。布尔值在.NET中没有一点大小,因此它们不是您想要的数据类型的良好存储。相反,请使用
位数组
——它仍然提供您所需的所有操作(读取一个位值,写入一个位值),并允许您在字节[]
中加载和存储整个数组(每个字节最多八位)。这使得持久性非常容易:
var data = new BitArray(File.ReadAllBytes("MyFile.bin"));
当然,这到底有多高效取决于分析。可能您不想加载数据,除非实际需要,所以某种分页解决方案可能更好;但这超出了您的问题范围。您可以将8位组合在一起,并将它们作为字节写入。我最困惑的是如何编写最简单的解析器和分段读取,以找到我在读取过程中的位置。不要重新发明轮子。我以前没有这样做过,所以这主要是理论上的。但我想你可以一次取8个布尔值,然后把它们变成一个
字节。基本上使用数学,对每个布尔值的字节应用位掩码。(我没有这样做,所以我不知道具体的数学是什么样子……但是对于任何给定的8位集合,你可以添加对应于该位位置的数值。2、4、8、16等等。)将该字节流写入文件的大小是将布尔值写入文件的大小的1/8。@不知道数据是什么样子(实际代码,而不仅仅是模糊的描述)就可以理解这很难说。你可以把8位组合在一起,然后把它们写成字节。我最困惑的是如何编写最简单的解析器,如何分段读取,以找到我在读取过程中的位置。不要重新发明轮子。我以前没有这样做过,所以这主要是理论上的。但我想你可以一次取8个布尔值,然后把它们变成一个字节。基本上使用数学,对每个布尔值的字节应用位掩码。(我没有这样做,所以我不知道具体的数学是什么样子……但是对于任何给定的8位集合,你可以添加对应于该位位置的数值。2、4、8、16等等。)将字节流写入文件的大小是将布尔值写入文件的大小的1/8。@在不知道数据的外观(实际代码,而不仅仅是模糊的描述)的情况下是可以理解的。我有无限的文件空间,我必须对每个布尔值执行大约100次读取操作,它存储在8位内存中,读取速度比位快,在位和布尔值之间转换和加载/保存是否容易?我根本不是程序员,我是工程师,我是在家学编程的。@当然可以理解BitArray
还有一个构造函数,它采用bool[]
,而CopyTo
方法同时适用于bool[]
和byte[]
。如果在您的场景中开销很大,那么手动读取和写入字节可能是值得的——这真的不难,只是简单的数学运算和正确处理边缘情况。将其视为一个锯齿状数组,其中每个字节
对应一个包含8个元素的bool[]
,访问字节中的一个元素的方式为byteVal&(20
(读取)和byteVal |=(2@Encrible这允许您保持文件小,同时快速实现内存中的表示。尽管我仍然会分析这件事,并确保将位保存在bool[]
中是值得的,但现在,假设并不是一个很好的决定方法:)操作bool可能更快/更便宜,但同时,您现在需要8 GiB的内存而不是1 GiB的内存;这类事情通常由内存访问模式决定,这些模式很难正确分析。访问是随机的还是顺序的?是否有比1D数组更好的组织,例如空间细分?@甚至可以理解如果加载字节并不复杂,而且数据看起来很大(内存方面),那么遵循Luan的建议是非常有意义的。谢谢你让我对任务的复杂性印象深刻。经过深思熟虑,在一些3D应用程序中使用sbyte而不是bool是有意义的,因为它是