我正在读取一个存储二进制文件的文件。在 python 中我可以轻松解码文件
>>> s = '0000000000A0A240'
>>> s.decode('hex')
'\x00\x00\x00\x00\x00\xa0\xa2@'
>>> import struct
>>> struct.unpack('d', s.decode('hex'))[0]
2384.0
Run Code Online (Sandbox Code Playgroud)
现在我想用Java做同样的解码,我们有类似的东西吗?
这里的话题很大,我是新手,我正在寻找一些方向,因为这个话题的可能性似乎无穷无尽。
我正在运行数值模拟,这会创建大量数据,我想不再将其存储在纯文本中(一旦我尝试保存创建的所有数据并最终得到一个 4TB txt 文件)。
我的模拟涉及一个间隔内的 4 个字段(每个字段由通常包含 4000 到 16000 个元素的双精度数组表示),并且它们每次都会演化大约 100 万个周期,因此我们正在谈论生成的数十亿个双精度。
当然,我不会每次都保存所有内容,而是使用 3 种类型的文件(这些文件是出于简短原因的模型,我的实际文件都是以 %g 格式编写的,因此它们采用这 7 个字符+表格):
保存所有时间步的特定点的字段内容的文件,例如:
t Phi Pi Delta A
0 1.3 0.4 0.3 0.99
...
Run Code Online (Sandbox Code Playgroud)保存特定时间步长的所有时间间隔内的所有字段的文件
x Phi Pi Delta A
0 0.0 0.4 0.0 1.0
...
Run Code Online (Sandbox Code Playgroud)保存每n步时间和空间的文件
t x Phi Pi Delta A
0.0 0.0 0.0 1.3 0.0 1.0
0.0 0.1 0.01 1.2 0.02 0.98
...
0.2 0.0 0.0 1.3 0.0 1.0
0.2 0.1 0.03 1.5 0.01 0.95
Run Code Online (Sandbox Code Playgroud)然后,我将这些文件用于各种目的,例如绘制图形、对它们进行傅里叶变换以及使用它们来恢复模拟。 …
有什么方法可以获取数据框,例如
df = pd.DataFrame({'a':[1,2,3], 'b':[4,5,6]})
Run Code Online (Sandbox Code Playgroud)
并将其作为二进制对象存储在临时内存中,然后可以使用
open(df, 'rb')
Run Code Online (Sandbox Code Playgroud)
那么,与其做类似的事情
open('/home/user/data.csv', 'rb')
Run Code Online (Sandbox Code Playgroud)
代码是
df = pd.DataFrame({'a':[1,2,3], 'b':[4,5,6]})
df_rb = *command to store in temp working memory as binary readable*
open(df_rb, 'rb')
Run Code Online (Sandbox Code Playgroud) 我正在观看Ben Eater 视频,注意到 bin 文件行的前 8 个字符都有某种形式的地址并记住了 COBOL。这些是相关的还是只是巧合?这只是一个使编译更容易的约定吗?
我想知道我们用于在 C 中打开文件的模式(文本或二进制)是否真的很重要。
例如,一般情况下,我们使用fread和fwrite来进行二进制模式的读写。当我们以文本模式打开文件时可以使用这些函数吗?
除此之外,一般情况下,我们可以使用fscanf和fprintf来进行文本模式的读写。如果我们以二进制模式打开文件,可以使用这些函数吗?
以文本或二进制模式打开文件会产生什么后果?
我想用浮点值将大文本文件的大小缩小为二进制.dat文件,所以我使用(在c ++中):
// the text stream
std::ifstream fin(sourceFile);
// the binary output stream
std::ofstream out(destinationFile, std::ios::binary);
float val;
while(!fin.eof())
{
fin >> val;
out.write((char *)&val,sizeof(float));
}
fin.close();
out.close();
Run Code Online (Sandbox Code Playgroud)
然后,我想将显式创建的二进制文件中的所有浮点值读取为浮点值数组.但是当我尝试从这个文件中读取时,我在最后一行代码(读取过程)中得到一个异常:
// test read
std::ifstream fstream(destinationFile, std::ios::binary);
__int64 fileSize = 0;
struct __stat64 fileStat;
if(0 == _tstat64(destinationFile, &fileStat))
{
fileSize = fileStat.st_size;
}
//get the number of float tokens in the file
size_t tokensCount = fileSize / sizeof(float);
float* pBuff = new float[tokensCount];
fstream.read((char*)&pBuff, tokensCount * sizeof(float));
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
我想使用C++找到二进制文件中第一次出现ANSI字符串.
我知道字符串类有一个方便的查找功能,但我不知道如果文件很大,我怎么能用它,比如5-10 MB.
我是否需要先将整个文件复制到内存中的字符串中?如果是,我如何确保在复制时没有任何二进制字符被破坏?
或者是否有更有效的方法来实现它,而无需将其复制到字符串中?
我同时使用多个进程操作txt文件(一些r/w操作).我看到了特殊标志的痕迹^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @偶尔在某些行上传播.这表明了什么?在什么情况下会出现这些符号.这是否意味着某些二进制内容被错误地写入了应该是文本的位置?
更新 我阅读了文档.有人认为这是由于linux/windows平台上的换行问题,而其他人则认为这是因为网络环境中的大端/小端.事实是我在网络文件系统中运行多个进程并操纵一个常见的txt文件.所以我猜编码格式可能是主要原因.谁可以建议如何避免这个问题?我不想编辑文件(比如手动进行文本替换).生成没有任何空字符的正确文件的简洁方法是首选.
UPDATE2 这是实现我的项目的python伪代码.fcntl.lockf就是将公共被操作文件锁定在多个运行多个进程的机器上.
while(manipulatedfile size is not 0):
open(manipulatedfile, 'r+') as fh:
fcntl.lockf(fh, fcntl.LOCK_EX)
all_lines = fh.readlines()
listing=all_lines[0:50] #get the first 50 lines
rest_lines = all_lines[50:] # …Run Code Online (Sandbox Code Playgroud) 我想附加一个先前编写的二进制文件,其中创建了一个更新的二进制文件.基本上合并它们.这是我使用的示例代码:
with open("binary_file_1", "ab") as myfile:
myfile.write("binary_file_2")
Run Code Online (Sandbox Code Playgroud)
除了我得到的错误 "TypeError: must be string or buffer, not file"
但这正是我想要做的!将一个二进制文件添加到先前创建的二进制文件的末尾.
我确实尝试添加"wb"到"myfile.write("binary_file_2", "wb")但它不喜欢那样.
我对此非常困惑.我转出一个大小为16000*4*2的3D数组,其中所有元素都是DOUBLE PRECISION,我认为我应该得到一个大小为16000*4*2*8字节/ dp = 1,024,000字节的文件.但我一直得到2,048,000字节.
我测试了一个简单的测试程序:
PROGRAM testprog
IMPLICIT NONE
DOUBLE PRECISION :: x=0.0D0
INTEGER :: i
OPEN(UNIT=128,FILE='try.out',FORM='UNFORMATTED',ACCESS='SEQUENTIAL')
DO i=1,16000*4*2
WRITE(128) x
ENDDO
CLOSE(128)
ENDPROGRAM testprog
Run Code Online (Sandbox Code Playgroud)
并使用以下命令运行它:
gfortran f.f90 -o a
./a
ls -als try.out
Run Code Online (Sandbox Code Playgroud)
而我得到的是
2000 -rw-r--r-- 1 jipuwang umstudents 2048000 Dec 17 20:16 try.out
Run Code Online (Sandbox Code Playgroud)
我无法理解它.一个双精度使用2个字节对吗?
我做了别的事,如果有人也能帮我理解这个:
PROGRAM testprog
IMPLICIT NONE
DOUBLE PRECISION :: x=0.0D0
INTEGER :: i
OPEN(UNIT=128,FILE='try.out')
DO i=1,2
WRITE(128,*) x
ENDDO
CLOSE(128)
ENDPROGRAM testprog
Run Code Online (Sandbox Code Playgroud)
它给了我一个大小为54字节的文件.