标签: binaryfiles

快速随机访问二进制文件,但也可以在需要时顺序访问.怎么布局?

我有大约10亿个数据集,它们有一个DatasetKey,每个数据集有1到5 000 000个子条目(一些对象),平均值大约是100,但有很多胖尾巴.

写入数据后,数据不会更新,只会读取数据.

我需要通过DatasetKey读取数据并执行以下操作之一:
获取子条目数
获取前1000个子条目(最大值小于1000)
获取前5000个子条目(最大值小于5000)
获取前100000个子条目(最大值如果小于100000)
获取所有子条目

每个子条目的大小约为20字节到2KB(平均450字节).

我想要使​​用的布局如下:

我创建了一个大小至少为5MB的文件.
每个文件至少包含一个DatasetKey,但如果文件仍然小于5MB,我添加新的DatasetKeys(带子条目),直到我超过5 MB.
首先,我存储一个标题,说明哪些文件偏移我会找到什么样的数据.
此外,我计划使用协议缓冲区存储序列化包.
前1000个条目的一个包,
一个用于接下来的4000个条目,
一个用于接下来的95000个条目,
一个用于下一个剩余的条目.

我将文件大小存储在RAM中(将所有标题存储在我使用的机器上所需的大量RAM中).当我需要访问特定的DatasetKey时,我在RAM中查找我需要的文件.然后我从RAM中获取文件大小.当文件大小约为5MB或更小时,我会将整个文件读入内存并进行处理.如果它超过5MB,我将只读取第一个xKB来获取标题.然后我从磁盘加载我需要的位置.

这听起来怎么样?这完全是胡说八道吗?还是一个好方法?

使用这个设计我有以下几点:

我想将我的数据存储在一个自己的二进制文件而不是数据库中,以便将来更容易备份和处理文件.
我会使用postgresql,但我想出存储二进制数据会使postgresqls-toast不止一次寻求访问数据.
为每个DatasetKey存储一个文件需要太多时间将所有值写入磁盘.
数据在RAM中计算(因为并非整个数据在RAM中同时拟合,它是以块为单位计算的).
5MB的文件大小只是一个粗略的估计.

你说什么?提前谢谢你的帮助!

编辑

更多背景资料:

DatasetKey的类型为ulong.

子条目(有不同的类型)大部分时间如下:

public struct ChildDataSet
{
    public string Val1;
    public string Val2;
    public byte Val3;
    public long Val4;
}
Run Code Online (Sandbox Code Playgroud)

我无法确切地知道访问了哪些数据.计划是用户可以访问特定DatasetKeys的前1000,5000,100000或所有数据.根据他们的设置.

我希望尽可能降低响应时间并尽可能少地使用磁盘空间.

@Regarding随机访问(Marc Gravells问题):

我不需要访问元素号.123456用于特定的DatasetKey.

当在一个文件中存储多个DatasetKey(带有子条目)时(我将其设计为不创建大量文件的方式),我需要随机访问该文件中特定DatasetKey的前1000个条目,或者第一个5000(所以我会阅读1000和4000包).

我只需要访问以下有关一个特定DatasetKey(uint)的内容:
1000个子条目(或所有子条目,如果小于1000)
5000个子条目(或所有子条目,如果小于5000)
100000个子条目(或所有子条目,如果小于100000)
所有子条目

我提到的所有其他事情只是一个设计尝试从我:-)

编辑,在一个类中流式传输一个列表?

public class ChildDataSet
{
    [ProtoMember(1)]
    public List<Class1> Val1;
    [ProtoMember(2)]
    public List<Class2> Val2;
    [ProtoMember(3)]
    public List<Class3> Val3; …
Run Code Online (Sandbox Code Playgroud)

c# binaryfiles protocol-buffers protobuf-net

5
推荐指数
1
解决办法
3041
查看次数

为什么git-status显示更新的二进制文件,并将新名称作为重命名?

在处理二进制文件时,git似乎考虑用另一个文件替换文件,修改文件重命名.例如,当用foo-1.0.3.jar或以下测试用例替换foo-1.0.1.jar时会发生这种情况:

$ dd if=/dev/urandom of=test.dat bs=1024 count=10
$ md5sum test.dat
8073aef704e9df13b44818371ebbcc0b  test.dat
$ git add test.dat && git commit -m 'add binary file'
$ mv test.dat test2.dat
$ git rm test.dat
$ dd if=/dev/urandom of=test2.dat bs=1 count=1 conv=notrunc
$ md5sum test2.dat
21e1ac3ab9ba50c9dad9171f9de7232d  test2.dat
$ git add test2.dat
Run Code Online (Sandbox Code Playgroud)

现在我清楚地有一个包含新内容(至少部分)和新名称的文件.但是,git认为这是一个重命名git status:

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       renamed:    test.dat -> test2.dat
Run Code Online (Sandbox Code Playgroud)
  • 这是什么原因,例如这两个文件有多相似?如果test2.dat包含完全不同的数据,似乎不会发生这种情况.
  • 除了看起来有点尴尬之外,它有什么缺点吗?实际数据似乎非常好; 在检查以前的版本时,我确实得到了该版本的正确文件.

git binaryfiles

5
推荐指数
1
解决办法
1353
查看次数

MATLAB:读取无符号16位二进制文​​件的两个字节

我有一个二进制Band Sequential(1波段,BSQ文件),它是一个无符号的16位(2字节)整数.

目前我通过multibandread读取整个(图像):

img=multibandread('IMAGE.bsq',[400 400 1],'uint16',0,'bsq','n');
Run Code Online (Sandbox Code Playgroud)

MATLAB中的哪个过程允许我单独读取两个字节?即我想在MATLAB中将文件读入2个新数组,例如byte1(400x400x1)和byte2(400x400x1).

这可以通过fread来实现吗?我注意到在'precision'部分中可以跳过源值(例如'N*source=>output'),但我不确定确切的过程.

matlab byte integer binaryfiles

5
推荐指数
1
解决办法
949
查看次数

Node.js二进制HTTP流

我需要从客户端(nodejs命令行)和服务器(表达nodejs)流式传输文件。

这是客户端:

var request = require('request');
var fs = require('fs');

// ...

  var readStream = fs.createReadStream(file.path);
  readStream.on('end', function() {
    that.emit('finished');
  });
  readStream.pipe(request.post(target));

// ...
Run Code Online (Sandbox Code Playgroud)

这是服务器端:

var fs = require('fs');
var path = require('path');

// ...

    app.post('/:filename', function(req, res) {
      req.setEncoding('binary');
      var filename = path.basename(req.params.filename);
      filename = path.resolve(destinationDir, filename);
      var dst = fs.createWriteStream(filename);
      req.pipe(dst);
      req.on('end', function() {
        res.send(200);
      });
    });

// ...
Run Code Online (Sandbox Code Playgroud)

一切正常,文件已正确保存在服务器端...但是它们比源文件大50%。我尝试查看两个文件之间的区别,hexdump并且服务器端文件的内容相似,但有时为0xC2。我想这与编码有关。

binaryfiles stream node.js express

5
推荐指数
1
解决办法
5286
查看次数

在Dart中连接字节

假设我有一个字节大小的整数列表.前4个字节(列表中的前4个项)实际上是单精度浮点数的组成部分.我想连接4个字节并将它们转换为浮点数.我该怎么做?

File myFile = new File('binaryfile.bin')
List<int> fileBytes = myFile.readAsBytes()
double myFloat = generateFloat(fileBytes.getRange(0, 4)); // how do I make this?
Run Code Online (Sandbox Code Playgroud)

types binaryfiles dart

5
推荐指数
1
解决办法
1035
查看次数

是否可以为 VS Code 编写二进制文件导入扩展?

我想在 vs code 中显示二进制文件的一些信息。是否可以为 VS Code 编写一个扩展名,以便在资源管理器中选择该文件(或直接打开它)时,您会看到该扩展名从二进制文件中提取的一些文本?

因此,该扩展的核心功能将是(简化的)二进制到文本转换器。

有什么建议么?

binaryfiles visual-studio-code

5
推荐指数
1
解决办法
1152
查看次数

使用Python将二进制文件上传到postgres服务器

我正在尝试将二进制文件上传到 postgres 服务器。我认为我正确地修改了Python脚本(https://gist.github.com/illume/8aa7c2d03273da846bf4361236a4f3f9#file-image_save-py),以便它将连接到我的postgres服务器,但我一直试图在命令行。据我了解,我需要导航到包含 image_save.py 脚本的目录并调用它。我还在同一目录中放置了一个测试文件,因此我尝试执行:

python image_save.py shuttle.jpg
Run Code Online (Sandbox Code Playgroud)

为此,我收到此错误:“错误:需要参数之一 --store --fetch 。”

然后我尝试:

python image_save.py --store shuttle.jpg
Run Code Online (Sandbox Code Playgroud)

我有:

  Traceback (most recent call last):
  File "image_save.py", line 45, in <module>
    main(sys.argv)
  File "image_save.py", line 30, in main
    curs.execute("INSERT INTO files(id, orig_filename, file_data) VALUES (DEFAULT,%s,%s) RETURNING id", (args.filename, filedata))
ValueError: A string literal cannot contain NUL (0x00) characters.
Run Code Online (Sandbox Code Playgroud)

我也尝试过:

python -m image_save.py shuttle.jpg
Run Code Online (Sandbox Code Playgroud)

我得到“C:\Python27\python.exe: 没有名为 image_save.py 的模块”

我真的认为我只是错误地调用了脚本。谁能看到我做错了什么吗?

python postgresql binary binaryfiles psql

5
推荐指数
1
解决办法
2675
查看次数

使用 pyspark 对大型二进制文件进行分区

尝试使用 PySpark 处理大型二进制文件,但总是出现 OutofMemoryError。尝试了所有可能的方法,例如增加执行器/驱动程序内存、重新分区 rdd。单个大型二进制文件会在 Spark 中进行分区吗?如果没有,我们如何处理二进制文件。我当前使用的二进制文件超过2GB。

binaryfiles apache-spark pyspark

5
推荐指数
0
解决办法
530
查看次数

如何解码/编码电缆调制解调器配置文件?

我目前正在研究DOCSIS及相关的一些内部工作原理。我有点困惑的一件事是如何制作电缆调制解调器配置文件。

根据我收集到的信息:

  • CM 配置是基于TLV格式的二进制文件。
  • 这些配置使用 TFTP 服务器进行部署,并在调制解调器启动时通过 DHCP 提示给调制解调器本身。

I'm interested in knowing how these config files are structured. I have next to no knowledge of TLV aside from what I've read these past days.

  • Is TLV just a generic method of stringing data together? It seems like TLV is used in both binary forms and json-like strings of clear text.
  • Is the T and/or L parts of TLV a set size (in bytes)? How do …

binaryfiles tlv

5
推荐指数
1
解决办法
3889
查看次数

从文件中高效读取结构化二进制数据

我有以下代码片段,用于读取二进制文件并验证它:

 FileStream f = File.OpenRead("File.bin");
 MemoryStream memStream = new MemoryStream();
 memStream.SetLength(f.Length);
 f.Read(memStream.GetBuffer(), 0, (int)f.Length);
 f.Seek(0, SeekOrigin.Begin);
 var r = new BinaryReader(f);
 Single prevVal=0;
 do
 {
    r.ReadUInt32();
    var val = r.ReadSingle();
    if (prevVal!=0) {
       var diff = Math.Abs(val - prevVal) / prevVal;
       if (diff > 0.25)
          Console.WriteLine("Bad!");
    }
    prevVal = val;
 }
 while (f.Position < f.Length);
Run Code Online (Sandbox Code Playgroud)

不幸的是,它运行速度非常慢,我正在寻求改进。在 C++ 中,我只需将文件读入字节数组,然后将该数组重新转换为结构数组:

struct S{
   int a;
   float b;
}
Run Code Online (Sandbox Code Playgroud)

我将如何在 C# 中执行此操作?

c# optimization binaryfiles

5
推荐指数
1
解决办法
1612
查看次数