web-dev-qa-db-ja.com

Python-リクエストを使用してファイルを直接メモリにダウンロードする

目標は、インターネットからファイルをダウンロードし、ハードドライブに触れることなくファイルオブジェクトまたはファイルのようなオブジェクトを作成することです。これは私の知る限りであり、特にファイル削除行をコーディングする必要を回避できるかどうかを知りたいので、それが可能か実用的かを知りたいのです。

これは私が通常ウェブから何かをダウンロードしてメモリにマッピングする方法です:

import requests
import mmap

u = requests.get("http://www.pythonchallenge.com/pc/def/channel.Zip")

with open("channel.Zip", "wb") as f: # I want to eliminate this, as this writes to disk
    f.write(u.content)

with open("channel.Zip", "r+b") as f: # and his as well, because it reads from disk
    mm = mmap.mmap(f.fileno(), 0)
    mm.seek(0)
    print mm.readline()
    mm.close() # question: if I do not include this, does this become a memory leak?
16
Akiva

これは私がやったことです。

import zipfile 
import requests
import StringIO

u = requests.get("http://www.pythonchallenge.com/pc/def/channel.Zip")
f = StringIO.StringIO() 
f.write(u.content)

def extract_Zip(input_Zip):
    input_Zip = zipfile.ZipFile(input_Zip)
    return {i: input_Zip.read(i) for i in input_Zip.namelist()}
extracted = extract_Zip(f)
6
Akiva

_r.raw_(HTTPResponse)はすでにファイルのようなオブジェクトです(_stream=True_を渡すだけです):

_#!/usr/bin/env python
import sys
import requests # $ pip install requests
from PIL import Image # $ pip install pillow

url = sys.argv[1]
r = requests.get(url, stream=True)
r.raw.decode_content = True # Content-Encoding
im = Image.open(r.raw) #NOTE: it requires pillow 2.8+
print(im.format, im.mode, im.size)
_

一般に、バイト文字列がある場合。 f = io.BytesIO(r.content)としてラップして、ディスクに触れることなくファイルのようなオブジェクトを取得できます。

_#!/usr/bin/env python
import io
import zipfile
from contextlib import closing
import requests # $ pip install requests

r = requests.get("http://www.pythonchallenge.com/pc/def/channel.Zip")
with closing(r), zipfile.ZipFile(io.BytesIO(r.content)) as archive:
    print({member.filename: archive.read(member) for member in archive.infolist()})
_

前者はシーク不可能なファイルであるため、_r.raw_をZipFile()に直接渡すことはできません。

ファイル削除行をコーディングする必要を回避できるかどうかを確認したい

tempfileはファイルを自動的に削除できます f = tempfile.SpooledTemporaryFile(); f.write(u.content).fileno()メソッドが呼び出される(一部のAPIが実際のファイルを必要とする場合)またはmaxsizeに到達するまで。データはメモリに保持されます。データがディスクに書き込まれている場合でも、ファイルは閉じるとすぐに削除されます。

25
jfs

あなたの答えはu.content。メモリ内のコンテンツis。ファイルに書き込まない限り、ディスクには保存されません。

7
poke