Python 获取错误“;ValueError:读取已关闭的文件;保存图像文件时在烧瓶中

Python 获取错误“;ValueError:读取已关闭的文件;保存图像文件时在烧瓶中,python,flask,Python,Flask,我有一个flask应用程序,可以从上传的jpeg文件中读取元数据。然后将元数据写入文本文件。我不断收到一个错误,我正在读取一个关闭的文件,但我知道我正在打开该文件 我有一个python脚本,它成功地从文件夹中的所有文件中读取元数据并将其写入文件。但是当我把代码放入flask应用程序时,我得到了错误 我的flask应用程序有一个python文件: app.py: import PIL import PIL.Image import PIL.ExifTags import pandas import

我有一个flask应用程序,可以从上传的jpeg文件中读取元数据。然后将元数据写入文本文件。我不断收到一个错误,我正在读取一个关闭的文件,但我知道我正在打开该文件

我有一个python脚本,它成功地从文件夹中的所有文件中读取元数据并将其写入文件。但是当我把代码放入flask应用程序时,我得到了错误

我的flask应用程序有一个python文件:

app.py:

import PIL
import PIL.Image
import PIL.ExifTags
import pandas
import os
from os import path
import shutil
import json
import requests
import datetime
from datetime import datetime
from datetime import timedelta
from flask import Flask , render_template, request

app = Flask(__name__)

a = datetime(1970,1,1,0,1,1)

api_token = 'donotputactualkey'
api_url_base = 'https://api.darksky.net/forecast/'

APP_ROOT = os.path.dirname(os.path.abspath(__file__))

LOG_ROOT = os.path.join(APP_ROOT,'logs')
if not os.path.isdir(LOG_ROOT):
    os.mkdir(LOG_ROOT)


if not path.isfile('logs/ErrorLog.txt'):
    err = open('logs/ErrorLog.txt','a')
    err.write('FileName, ErrorDesc,DateTime \n')
    err.close()
else:
    err = open('logs/ErrorLog.txt','a')



if not path.isfile('logs/PhotoLatLong.txt'):
    log = open('logs/PhotoLatLong.txt','a')
    log.write('FileName,DateTaken,Lat,Long,precipIntensity,PrecipProbability,temperature,apparentTemperature,dewPoint,humidity,pressure,windSpeed,windGust,windBearing,CloudCover,uvIndex,visibility,nearest-station \n')
    log.close()
else:
    log = open('logs/PhotoLatLong.txt','a')


@app.route('/')
def index():
    return render_template('upload.html')

@app.route('/upload', methods = ['GET','POST'])
def upload():
    target = os.path.join(APP_ROOT,'images/')
    print(target)

    if not os.path.isdir(target):
        os.mkdir(target)
    CurDate = str(datetime.now()).split('.')[0]
    if err.closed:
        open(err)
    if log.closed:
        open(log)
    for file in request.files.getlist('file'):
        FileName = file.name
        print(FileName)
        img = PIL.Image.open(file)
        exif_data = img._getexif()
        if 306 not in exif_data.keys():
            print(str(File)+' has no datetime stamp')
            err.write(str(FileName+', No Date found,'+CurDate+'\n'))
            err.close()
        else:
            DateTaken =   exif_data[306]
            ApiDate = DateTaken[:4]+'-'+DateTaken[5:7]+'-'+DateTaken[8:10]+'T'+DateTaken[11:19]
            FileDate = DateTaken[:4]+'-'+DateTaken[5:7]+'-'+DateTaken[8:10]+' '+DateTaken[11:19]
            b = datetime(int(DateTaken[:4]),int(DateTaken[5:7]),int(DateTaken[8:10]),int(DateTaken[11:13]),int(DateTaken[14:16]),int(DateTaken[17:20]))
            newval = exif_data.get(34853)
        if 2 not in newval:
            err.write(str(str(FileName) +', GPS info not found,'+str(datetime.now()).split('.')[0]+'\n'))
            err.close()
        else:
            latdegs = exif_data[34853][2][0][0]
            latmins = exif_data[34853][2][1][0]
            latsecs = exif_data[34853][2][2][0]  / exif_data[34853][2][2][1]
            latcoords = latdegs + latmins/60 + latsecs/3600
            longdegs = exif_data[34853][4][0][0]
            longmins = exif_data[34853][4][1][0]
            longsecs = exif_data[34853][4][2][0]  / exif_data[34853][4][2][1]
            longcoords = longdegs + longmins/60 + longsecs/3600
            longcoords = longcoords * -1
            api_url_latlon = str(latcoords) +','+str(longcoords)
            time = ',' +ApiDate
            response = requests.get(api_url_base+api_token+'/'+api_url_latlon+time)
            dataapi = json.loads(response.content.decode('utf-8'))
            TT = (b-a).total_seconds()
            T1 = dataapi['hourly']['data'][0]['time']
            T2 = dataapi['hourly']['data'][1]['time']
            T3 = dataapi['hourly']['data'][2]['time']
            T4 = dataapi['hourly']['data'][3]['time']
            T5 = dataapi['hourly']['data'][4]['time']
            d = {0:TT-T1, 1:TT-T2, 2:TT-T3, 3:TT-T4, 4:TT-T5}
            k = min(d.items(),key=lambda x: x[1])
            pi = str(dataapi['hourly']['data'][k[0]]['precipIntensity'])
            pp = str(dataapi['hourly']['data'][k[0]]['precipProbability'])
            t = str(dataapi['hourly']['data'][k[0]]['temperature'])
            at = str(dataapi['hourly']['data'][k[0]]['apparentTemperature'])
            dp = str(dataapi['hourly']['data'][k[0]]['dewPoint'])
            hum = str(dataapi['hourly']['data'][k[0]]['humidity'])
            pr = str(dataapi['hourly']['data'][k[0]]['pressure'])
            ws = str(dataapi['hourly']['data'][k[0]]['windSpeed'])
            wg = str(dataapi['hourly']['data'][k[0]]['windGust'])
            wb = str(dataapi['hourly']['data'][k[0]]['windBearing'])
            cc = str(dataapi['hourly']['data'][k[0]]['cloudCover'])
            uv = str(dataapi['hourly']['data'][k[0]]['uvIndex'])
            vi = str(dataapi['hourly']['data'][k[0]]['visibility'])
            log.write(str(str(FileName) +','+str(FileDate)+','+str(latcoords)+','+str(longcoords)+','+pi+','+pp+','+t+','+at+','+dp+','+hum+','+pr+','+ws+','+wb+','+cc+','+uv+','+vi+'\n') )
            img.close()
            log.close()

        print(file)
        filename = file.filename
        destination = '/'.join([target, filename])
        print(destination)
        file.save(destination)

    return render_template('complete.html')


if __name__ == "__main__":
    app.run(debug = True)
预期被重定向到“complete.html”,但控制台显示此错误:

 * Serving Flask app "app" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 964-871-100
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
C:\Users\denjs\Documents\UdemyFlaskReview\PicUpload\images/
file
<FileStorage: 'P5040063.JPG' ('image/jpeg')>
C:\Users\denjs\Documents\UdemyFlaskReview\PicUpload\images//P5040063.JPG
127.0.0.1 - - [16/Aug/2019 13:39:02] "POST /upload HTTP/1.1" 500 -
Traceback (most recent call last):
  File "C:\Users\denjs\AppData\Local\conda\conda\envs\mynewflaskenv\lib\site-packages\flask\app.py", line 2309, in __call__
    return self.wsgi_app(environ, start_response)
  File "C:\Users\denjs\AppData\Local\conda\conda\envs\mynewflaskenv\lib\site-packages\flask\app.py", line 2295, in wsgi_app
    response = self.handle_exception(e)
  File "C:\Users\denjs\AppData\Local\conda\conda\envs\mynewflaskenv\lib\site-packages\flask\app.py", line 1741, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Users\denjs\AppData\Local\conda\conda\envs\mynewflaskenv\lib\site-packages\flask\_compat.py", line 35, in reraise
    raise value
  File "C:\Users\denjs\AppData\Local\conda\conda\envs\mynewflaskenv\lib\site-packages\flask\app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\Users\denjs\AppData\Local\conda\conda\envs\mynewflaskenv\lib\site-packages\flask\app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "C:\Users\denjs\AppData\Local\conda\conda\envs\mynewflaskenv\lib\site-packages\flask\app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Users\denjs\AppData\Local\conda\conda\envs\mynewflaskenv\lib\site-packages\flask\_compat.py", line 35, in reraise
    raise value
  File "C:\Users\denjs\AppData\Local\conda\conda\envs\mynewflaskenv\lib\site-packages\flask\app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\Users\denjs\AppData\Local\conda\conda\envs\mynewflaskenv\lib\site-packages\flask\app.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "C:\Users\denjs\Documents\UdemyFlaskReview\PicUpload\app.py", line 123, in upload
    file.save(destination)
  File "C:\Users\denjs\AppData\Local\conda\conda\envs\mynewflaskenv\lib\site-packages\werkzeug\datastructures.py", line 2728, in save
    copyfileobj(self.stream, dst, buffer_size)
  File "C:\Users\denjs\AppData\Local\conda\conda\envs\mynewflaskenv\lib\shutil.py", line 79, in copyfileobj
    buf = fsrc.read(length)
  File "C:\Users\denjs\AppData\Local\conda\conda\envs\mynewflaskenv\lib\tempfile.py", line 740, in read
    return self._file.read(*args)
  File "C:\Users\denjs\AppData\Local\conda\conda\envs\mynewflaskenv\lib\tempfile.py", line 485, in func_wrapper
    return func(*args, **kwargs)
ValueError: read of closed file
127.0.0.1 - - [16/Aug/2019 13:39:02] "GET /upload?__debugger__=yes&cmd=resource&f=style.css HTTP/1.1" 200 -
127.0.0.1 - - [16/Aug/2019 13:39:02] "GET /upload?__debugger__=yes&cmd=resource&f=debugger.js HTTP/1.1" 200 -
127.0.0.1 - - [16/Aug/2019 13:39:02] "GET /upload?__debugger__=yes&cmd=resource&f=jquery.js HTTP/1.1" 200 -
127.0.0.1 - - [16/Aug/2019 13:39:02] "GET /upload?__debugger__=yes&cmd=resource&f=console.png HTTP/1.1" 200 -
127.0.0.1 - - [16/Aug/2019 13:39:02] "GET /upload?__debugger__=yes&cmd=resource&f=ubuntu.ttf HTTP/1.1" 200 -
*服务烧瓶应用程序“应用程序”(延迟加载)
*环境:生产
警告:不要在生产环境中使用开发服务器。
改用生产WSGI服务器。
*调试模式:打开
*使用stat重新启动
*调试器处于活动状态!
*调试器PIN:964-871-100
*继续http://127.0.0.1:5000/ (按CTRL+C退出)
C:\Users\denjs\Documents\UdemyFlaskReview\PicUpload\images/
文件
C:\Users\denjs\Documents\UdemyFlaskReview\PicUpload\images//P5040063.JPG
127.0.0.1---[16/Aug/2019 13:39:02]“发布/上传HTTP/1.1”500-
回溯(最近一次呼叫最后一次):
文件“C:\Users\denjs\AppData\Local\conda\conda\envs\mynewflaskenv\lib\site packages\flask\app.py”,第2309行,在调用中__
返回self.wsgi_应用程序(环境,启动响应)
wsgi_应用程序中的文件“C:\Users\denjs\AppData\Local\conda\conda\envs\mynewflaskenv\lib\site packages\flask\app.py”,第2295行
response=self.handle\u异常(e)
文件“C:\Users\denjs\AppData\Local\conda\conda\envs\mynewflaskenv\lib\site packages\flask\app.py”,第1741行,在句柄中
重放(exc_类型、exc_值、tb)
文件“C:\Users\denjs\AppData\Local\conda\conda\envs\mynewflaskenv\lib\site packages\flask\\u compat.py”,第35行,重新登录
增值
wsgi_应用程序中的文件“C:\Users\denjs\AppData\Local\conda\conda\envs\mynewflaskenv\lib\site packages\flask\app.py”,第2292行
response=self.full\u dispatch\u request()
文件“C:\Users\denjs\AppData\Local\conda\conda\envs\mynewflaskenv\lib\site packages\flask\app.py”,第1815行,完整发送请求
rv=自身处理用户异常(e)
文件“C:\Users\denjs\AppData\Local\conda\conda\envs\mynewflaskenv\lib\site packages\flask\app.py”,第1718行,在handle\u user\u异常中
重放(exc_类型、exc_值、tb)
文件“C:\Users\denjs\AppData\Local\conda\conda\envs\mynewflaskenv\lib\site packages\flask\\u compat.py”,第35行,重新登录
增值
文件“C:\Users\denjs\AppData\Local\conda\conda\envs\mynewflaskenv\lib\site packages\flask\app.py”,第1813行,完整发送请求
rv=自我分派请求()
文件“C:\Users\denjs\AppData\Local\conda\conda\envs\mynewflaskenv\lib\site packages\flask\app.py”,第1799行,在调度请求中
返回self.view_函数[rule.endpoint](**req.view_参数)
文件“C:\Users\denjs\Documents\UdemyFlaskReview\PicUpload\app.py”,上传中第123行
文件保存(目标)
文件“C:\Users\denjs\AppData\Local\conda\conda\envs\mynewflaskenv\lib\site packages\werkzeug\datastructures.py”,第2728行,保存
copyfileobj(self.stream、dst、缓冲区大小)
copyfileobj中的文件“C:\Users\denjs\AppData\Local\conda\conda\envs\mynewflaskenv\lib\shutil.py”,第79行
buf=fsrc.read(长度)
文件“C:\Users\denjs\AppData\Local\conda\conda\envs\mynewflaskenv\lib\tempfile.py”,第740行,已读
返回self.\u file.read(*args)
文件“C:\Users\denjs\AppData\Local\conda\conda\envs\mynewflaskenv\lib\tempfile.py”,第485行,在func_包装中
返回函数(*args,**kwargs)
ValueError:读取已关闭的文件
127.0.0.1---[16/Aug/2019 13:39:02]“获取/上载?\uuuuuu调试器\uuuuuuuuuuu=yes&cmd=resource&f=style.css HTTP/1.1”200-
127.0.0.1---[16/Aug/2019 13:39:02]“获取/上载?\uuuuuu调试器\uuuuuuuuuu=yes&cmd=resource&f=debugger.js HTTP/1.1”200-
127.0.0.1---[16/Aug/2019 13:39:02]“获取/上传?\uuuuuu调试器\uuuuuuuuuu=yes&cmd=resource&f=jquery.js HTTP/1.1”200-
127.0.0.1---[16/Aug/2019 13:39:02]“获取/上载?\uuuuuu调试器\uuuuuuuuuuu=yes&cmd=resource&f=console.png HTTP/1.1”200-
127.0.0.1---[16/Aug/2019 13:39:02]“获取/上传?\uuuuuu调试器\uuuuuuuuuuu=yes&cmd=resource&f=ubuntu.ttf HTTP/1.1”200-

这是因为您已经用PIL关闭了底层文件对象:

用于request.files.getlist('file')中的文件:
FileName=file.name
打印(文件名)
img=PIL.Image.open(文件)
...
其他:
...
img.close()#
for file in request.files.getlist('file'):
    destination = '/'.join([target, filename])
    file.save(destination)