所以我在服務器上有一個非常大的檔案(3GB ),其中包含用戶需要訪問的SMILES串列。
例子:
smile id
0 CC(C)C(=O)Nc1nc2c(ncn2CC(=O)N2[C@@H]3CC[C@H]2C[C@@H](NC(=O)c2cnc[nH]2)C3)c(O)n1 ZINC001801458702
1 O=C(c1ccc(O)c([N ](=O)[O-])c1)N1CC[C@@]2(C1)CN(C(=O)[C@@H]1CC(=O)N(C3CCCC3)C1)CCO2 ZINC001781539777
2 C[C@@H]1CCc2c(C(=O)Nc3cc([C@@H]4CCCCN4C(=O)c4ccc5c(n4)NC(=O)CC5)[nH]n3)n[nH]c21 ZINC001818636963
3 O=C(CN1C(=O)C=CC1=O)N1CCC2(CCCN(C(=O)[C@H]3CCc4nc(O)nc(O)c4C3)C2)CC1 ZINC001807092425
4 NC(=O)c1nccnc1C(=O)N1CCC2(CCCN(C(=O)[C@@H]3CCc4nc(O)nc(O)c4C3)C2)CC1 ZINC001807092030
但通常用戶只想要檔案的一個小樣本而不是整個檔案,所以我需要一種方法來快速有效地發送檔案的前 n 行(即不必創建一個新檔案來發送) .
我現在這樣做的方式是創建一個只包含那些 n 行的新檔案,然后發送它:
# Open our current file (3GB )
with open(old_file_path, "r") as old_file:
# Open our new file and write the n lines to it
with open(new_file_path, "w") as reduced_smile_file:
# Write lines to new file
for _ in range(quantity):
# Read and store the line
line = smile_file.readline()
# Check if the line is empty
# This happend when lines in the smile file are less than requested
if len(line) == 0:
break
# Write to the file
reduced_smile_file.write(line)
# Open the newly created file with the n lines
f = open(new_file_path, 'rb')
# Send the new file
response = flask.send_file(f, as_attachment=True, download_name="smile.csv")
# Delete the new file
os.remove(new_file_path)
return response
所以基本上我想知道的是:
是否可以通過 Flask 僅發送檔案的前 n 行?
先感謝您!
uj5u.com熱心網友回復:
我認為您可以使用generatorwhich 將for-loopyield僅用于幾行前幾行,并且在回圈之后它將自動關閉連接。
檔案:流媒體內容
最小的作業示例
我io.StringIO用來模擬檔案,但你可以使用open(),close()
如果你連接http://127.0.0.1:5000/3那么你應該只得到 3 行。
from flask import Flask
import io
data = '''smile id
0 CC(C)C(=O)Nc1nc2c(ncn2CC(=O)N2[C@@H]3CC[C@H]2C[C@@H](NC(=O)c2cnc[nH]2)C3)c(O)n1 ZINC001801458702
1 O=C(c1ccc(O)c([N ](=O)[O-])c1)N1CC[C@@]2(C1)CN(C(=O)[C@@H]1CC(=O)N(C3CCCC3)C1)CCO2 ZINC001781539777
2 C[C@@H]1CCc2c(C(=O)Nc3cc([C@@H]4CCCCN4C(=O)c4ccc5c(n4)NC(=O)CC5)[nH]n3)n[nH]c21 ZINC001818636963
3 O=C(CN1C(=O)C=CC1=O)N1CCC2(CCCN(C(=O)[C@H]3CCc4nc(O)nc(O)c4C3)C2)CC1 ZINC001807092425
4 NC(=O)c1nccnc1C(=O)N1CCC2(CCCN(C(=O)[C@@H]3CCc4nc(O)nc(O)c4C3)C2)CC1 ZINC001807092030'''
app = Flask(__name__)
def generate(quantity):
f = io.StringIO(data)
#f = open(filename, 'r')
for _ in range(quantity):
yield f.readline()
#f.close()
@app.route('/')
@app.route('/<int:number>')
def index(number=1):
response = app.response_class(generate(number), mimetype='text/csv')
response.headers['Content-Disposition'] = 'attachment; filename="smile.csv"'
return response
if __name__ == '__main__':
#app.debug = True
app.run()
編輯:
您可以運行的版本/end或/start/end
from flask import Flask, send_file
import io
data = '''smile id
0 CC(C)C(=O)Nc1nc2c(ncn2CC(=O)N2[C@@H]3CC[C@H]2C[C@@H](NC(=O)c2cnc[nH]2)C3)c(O)n1 ZINC001801458702
1 O=C(c1ccc(O)c([N ](=O)[O-])c1)N1CC[C@@]2(C1)CN(C(=O)[C@@H]1CC(=O)N(C3CCCC3)C1)CCO2 ZINC001781539777
2 C[C@@H]1CCc2c(C(=O)Nc3cc([C@@H]4CCCCN4C(=O)c4ccc5c(n4)NC(=O)CC5)[nH]n3)n[nH]c21 ZINC001818636963
3 O=C(CN1C(=O)C=CC1=O)N1CCC2(CCCN(C(=O)[C@H]3CCc4nc(O)nc(O)c4C3)C2)CC1 ZINC001807092425
4 NC(=O)c1nccnc1C(=O)N1CCC2(CCCN(C(=O)[C@@H]3CCc4nc(O)nc(O)c4C3)C2)CC1 ZINC001807092030'''
app = Flask(__name__)
def generate(start, end):
f = io.StringIO(data)
#f = open(filename, 'r')
# skip lines
for _ in range(start):
f.readline()
for i in range(end-start):
yield f.readline()
@app.route('/')
@app.route('/<int:end>')
@app.route('/<int:start>/<int:end>')
def index(start=0, end=1):
response = app.response_class(generate(start, end), mimetype='text/csv')
response.headers['Content-Disposition'] = 'attachment; filename="smile.csv"'
return response
if __name__ == '__main__':
#app.debug = True
app.run()
您可以將檔案名設定為標題response_class
def index(start=0, end=1):
headers = {'Content-Disposition': 'attachment; filename="smile2.csv"'}
response = app.response_class(generate(start, end), headers=headers, mimetype='text/csv')
return response
編輯:
如果您有行的位置(檔案中的偏移量),那么您可以使用read(position)而不是for-loop 和readline()- 它會將位元組從檔案的開頭發送到position
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/443957.html
標籤:Python 烧瓶 python-3.8
