Я хотел бы сделать следующее в Python 3: Чтение в FortranFile, но по URL, а не из локального файла. Причина в том, что в моем конкретном примере есть много файлов, и я хочу избежать первой загрузки их всех.
Мне удалось
a) прочитать в простом .txt файл с URL
import urllib from urllib.request import urlopen url='http://www.deus-consortium.org/deus-library/filelist/deus_file_list_501.txt' data=urllib.request.urlopen(url) i=0 for line in data: # files are iterable print(i,line) i+=1 #alternative: data.read()
b) читается в локальном FortranFile (двоичный неформатированный файл Fortran с прямым порядком байтов) следующим образом:
Файл из: http://www.deus-consortium.org/deus-library/efiler1/Babel_le/boxlen648_n2048_lcdmw7/post/fof/output_00090/fof_boxlen648_n2048_lcdmw7_masst_00000
from scipy.io import FortranFile filename='../../Downloads/fof_boxlen648_n2048_rpcdmw7_masst_00000' ff = FortranFile(filename, 'r') nhalos=ff.read_ints(dtype=np.int32)[0] print('number of halos in file',nhalos)
Есть ли способ избежать загрузки и чтения файлов FortranFiles непосредственно с URL-адреса? Я пытался
import urllib from urllib.request import urlopen url='http://www.deus-consortium.org/deus-library/efiler1/Babel_le/boxlen648_n2048_lcdmw7/cube_00090/fof_boxlen648_n2048_lcdmw7_cube_00000' pathname = urllib.request.urlopen(url) ff = FortranFile(pathname, 'r') ff.read_ints()
выдавать «Ошибка OSE: получение позиции файла не удалось». pathname.read() тоже не работает, потому что это файл на фортране.
pathname.read()
Есть идеи? Заранее спасибо!
Может быть, вы можете использовать tempfile модуль для загрузки и чтения данных?
tempfile
Например:
import urllib import tempfile from scipy.io import FortranFile from urllib.request import urlopen url='http://www.deus-consortium.org/deus-library/efiler1/Babel_le/boxlen648_n2048_lcdmw7/cube_00090/fof_boxlen648_n2048_lcdmw7_cube_00000' with tempfile.TemporaryFile() as fp: fp.write(urllib.request.urlopen(url).read()) fp.seek(0) ff = FortranFile(fp, 'r') info = ff.read_ints() print(info)
Отпечатки:
[12808737]