qq_笑_17
更新的答案我在Numpy中对此进行了更多尝试,您可以像这样更干净地阅读文件 - 以下信息仍然适用并解释了它的工作原理:import numpy as np# Read file and reshape as "records" of 28 bytes eachn = np.fromfile('fort.99',dtype=np.uint8).reshape(-1,28)I = n[:,4:8].copy().view(np.int32) # pick bytes 4-8, make contiguous and view as integerA = n[:,8:16].copy().view(np.float64) # pick bytes 8-16, make contiguous and view as float64B = n[:,16:24].copy().view(np.float64) # pick bytes 16-24, make contiguous and view as float64原始答案我更改了您的程序以包含一些可识别的数据: program thing REAL*8, DIMENSION(128) :: A,B INTEGER N N=128 open(unit=99,form='unformatted',status='unknown') do i=1,N A(i)=100.0 * i B(i)=-1000.0 * i write(99) (2*i),(A(i)),(B(i)) enddo close(99) end program然后我查看了文件大小,它是3,584字节,所以我将其除以128,以获得每个fortran的字节数为28。WRITE因此,按如下方式检查了数据:xxdxxd -c 28 fort.9900000000: 1400 0000 0200 0000 0000 0000 0000 5940 0000 0000 0040 8fc0 1400 0000 ..............Y@.....@......0000001c: 1400 0000 0400 0000 0000 0000 0000 6940 0000 0000 0040 9fc0 1400 0000 ..............i@.....@......00000038: 1400 0000 0600 0000 0000 0000 00c0 7240 0000 0000 0070 a7c0 1400 0000 ..............r@.....p......00000054: 1400 0000 0800 0000 0000 0000 0000 7940 0000 0000 0040 afc0 1400 0000 ..............y@.....@......00000070: 1400 0000 0a00 0000 0000 0000 0040 7f40 0000 0000 0088 b3c0 1400 0000 .............@.@............0000008c: 1400 0000 0c00 0000 0000 0000 00c0 8240 0000 0000 0070 b7c0 1400 0000 ...............@.....p......000000a8: 1400 0000 0e00 0000 0000 0000 00e0 8540 0000 0000 0058 bbc0 1400 0000 ...............@.....X......000000c4: 1400 0000 1000 0000 0000 0000 0000 8940 0000 0000 0040 bfc0 1400 0000 ...............@.....@......000000e0: 1400 0000 1200 0000 0000 0000 0020 8c40 0000 0000 0094 c1c0 1400 0000 ............. .@............000000fc: 1400 0000 1400 0000 0000 0000 0040 8f40 0000 0000 0088 c3c0 1400 0000 .............@.@............因此,每个 fortran WRITE 有 28 个字节,每个记录的开头和结尾有 4 个字节的索引。然后我像这样解码它们:#!/usr/bin/env python3import struct# Important to open the file in binary mode, 'b'with open('fort.99','rb') as f: # You should really read until error in case there are more or fewer than 128 records one day - but you know there are 128 for i in range(128): # Read one record, i.e. output of one fortran WRITE record = f.read(28) # Unpack 2 INTEGERs, 2 DOUBLEs and an INTEGER _, I, A, B, _ = struct.unpack('2i2di',record) print(I,A,B)输出2 100.0 -1000.04 200.0 -2000.06 300.0 -3000.08 400.0 -4000.010 500.0 -5000.012 600.0 -6000.014 700.0 -7000.016 800.0 -8000.018 900.0 -9000.020 1000.0 -10000.022 1100.0 -11000.024 1200.0 -12000.026 1300.0 -13000.028 1400.0 -14000.030 1500.0 -15000.032 1600.0 -16000.034 1700.0 -17000.036 1800.0 -18000.038 1900.0 -19000.040 2000.0 -20000.042 2100.0 -21000.044 2200.0 -22000.046 2300.0 -23000.048 2400.0 -24000.050 2500.0 -25000.052 2600.0 -26000.054 2700.0 -27000.056 2800.0 -28000.058 2900.0 -29000.060 3000.0 -30000.062 3100.0 -31000.064 3200.0 -32000.066 3300.0 -33000.068 3400.0 -34000.070 3500.0 -35000.072 3600.0 -36000.074 3700.0 -37000.076 3800.0 -38000.078 3900.0 -39000.080 4000.0 -40000.082 4100.0 -41000.084 4200.0 -42000.086 4300.0 -43000.088 4400.0 -44000.090 4500.0 -45000.092 4600.0 -46000.094 4700.0 -47000.096 4800.0 -48000.098 4900.0 -49000.0100 5000.0 -50000.0102 5100.0 -51000.0104 5200.0 -52000.0106 5300.0 -53000.0108 5400.0 -54000.0110 5500.0 -55000.0112 5600.0 -56000.0114 5700.0 -57000.0116 5800.0 -58000.0118 5900.0 -59000.0120 6000.0 -60000.0122 6100.0 -61000.0124 6200.0 -62000.0126 6300.0 -63000.0128 6400.0 -64000.0130 6500.0 -65000.0132 6600.0 -66000.0134 6700.0 -67000.0136 6800.0 -68000.0138 6900.0 -69000.0140 7000.0 -70000.0142 7100.0 -71000.0144 7200.0 -72000.0146 7300.0 -73000.0148 7400.0 -74000.0150 7500.0 -75000.0152 7600.0 -76000.0154 7700.0 -77000.0156 7800.0 -78000.0158 7900.0 -79000.0160 8000.0 -80000.0162 8100.0 -81000.0164 8200.0 -82000.0166 8300.0 -83000.0168 8400.0 -84000.0170 8500.0 -85000.0172 8600.0 -86000.0174 8700.0 -87000.0176 8800.0 -88000.0178 8900.0 -89000.0180 9000.0 -90000.0182 9100.0 -91000.0184 9200.0 -92000.0186 9300.0 -93000.0188 9400.0 -94000.0190 9500.0 -95000.0192 9600.0 -96000.0194 9700.0 -97000.0196 9800.0 -98000.0198 9900.0 -99000.0200 10000.0 -100000.0202 10100.0 -101000.0204 10200.0 -102000.0206 10300.0 -103000.0208 10400.0 -104000.0210 10500.0 -105000.0212 10600.0 -106000.0214 10700.0 -107000.0216 10800.0 -108000.0218 10900.0 -109000.0220 11000.0 -110000.0222 11100.0 -111000.0224 11200.0 -112000.0226 11300.0 -113000.0228 11400.0 -114000.0230 11500.0 -115000.0232 11600.0 -116000.0234 11700.0 -117000.0236 11800.0 -118000.0238 11900.0 -119000.0240 12000.0 -120000.0242 12100.0 -121000.0244 12200.0 -122000.0246 12300.0 -123000.0248 12400.0 -124000.0250 12500.0 -125000.0252 12600.0 -126000.0254 12700.0 -127000.0256 12800.0 -128000.0如您所见,每条记录上都有记录标记,这意味着记录的长度为20个字节(1个fortran INTEGER@4,2个fortran DOUBLE@8),每端都有4个字节的记录标记 - 我将其读入Python中调用并丢弃的变量中。如果你不想要这样,你需要在fortran中使用/输出 - 但我不知道你是否可以在处理链的另一端控制它。有关说明,请参阅此处。1400 0000_DIRECTSTREAM关键字: fortran, Python, 二进制, 无格式, xxd, 转储, 记录, 视图为整数, 视图为浮点数, 视图为浮点64, 视图为双精度