这是二进制文件:
ftp://n5eil01u.ecs.nsidc.org/SAN/GLAS/GLA14.034/2003.02.28/GLA14_634_1102_002_0071_0_01_0001.DAT
我试图读取该文件:
fname = "GLA14_634_1102_002_0071_0_01_0001.DAT"
with open (fname, 'rb') as fi:
lines = fi.read().splitlines()
print len(lines)
print lines[-1]
行数T 844514'似乎是对的。
但最后一行显示为不可读的字符。
我怎样才能正确阅读?
答案 0 :(得分:0)
缩短的示例文件的“最后一行”以这些字节开头:
In [49]: lines[-1][:20]
Out[49]: b'\x01\xa8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
将其转换为int
:
In [50]: [int(x) for x in lines[-1][:20]]
Out[50]: [1, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
在lines[-1][1]
上,我们168
超出了ASCII范围。
如果要将其转换为可打印的字符,则必须找出此文件中使用的编码。
修改强>
如果您可以使用类UNIX系统,则可以使用strings
util(man page)。
$ strings GLA14_634_1102_002_0071_0_01_0001.DAT | head -20
Recl=10000;
Numhead=2;
size_mb_ecs_data_granule=267.57240295410156;
time_between_contiguous_records=1;
instrument_short_name=GLAS;
platform_short_name=Icesat;
sensor_short_name=LaserAlt;
glas_osc_rate.1=1.000000028;
glas_osc_rate_date.1=2003-02-20;
glas_osc_rate_time.1=00:00:00;
sc_osc_rate.1=0.99999998864727;
sc_osc_rate_date.1=2003-02-20;
sc_osc_rate_time.1=00:00:00;
internal_time_delay.1=15.11;
internal_time_delay_date.1=2003-02-20;
internal_time_delay_time.1=00:00:00;
internal_range_delay.1=9556;
internal_range_delay_date.1=2003-02-20;
internal_range_delay_time.1=00:00:00;
ReprocessingPlanned=no further update anticipated;
答案 1 :(得分:0)
该文件似乎是混合文本和二进制文件。前20000个字节是文本,然后是一些二进制数据。似乎没有引用文本部分中二进制数据的开头。所以我认为20000字节是固定的。
所以你得到文本部分:
TEXT_PART_SIZE = 20000
filename = "GLA14_634_1102_002_0071_0_01_0001.DAT"
with open(filename, 'rb') as data:
text_lines = data.read(TEXT_PART_SIZE).strip().splitlines()
文本行提供了一些元数据,可能用于解码以下二进制数据。没有详细的描述就不可能读取这个二进制数据。看来,有15个数据集和200个单独的文件打包在一个大文件中。
借助struct
- 模块和文件格式说明,您可以轻松阅读此类文件。
答案 2 :(得分:0)
您正在使用GLA14 ICESat数据记录。您想要的有关字节结构的信息也应该在NSIDC(https://nsidc.org/data/docs/daac/glas_altimetry/gla14_records.html)中找到。至于ascii文本标题,每个人都是正确的,有一个固定的长度。该长度由前两个ascii行描述(Recl = 10000,即记录长度,Numhead = 2,即标题中10000字节长度记录的数量),在您读取这20000字节后,您将开始读取GLA14变量。