2012-02-23 2 views
3

Вот тест, который я создал, чтобы воссоздать проблему, с которой я столкнулся, когда использовал tempfile.NamedTemporaryFile(). Проблема в том, что когда я использую tempfile, данные в моем CSV усекаются с конца файла.Почему tempfile.NamedTemporaryFile() урезает мои данные?

Когда вы запустите этот тестовый скрипт, temp2.csv будет усечен, а temp1.csv будет такого же размера, как и исходный CSV.

Я использую Python 2.7.1.

Вы можете скачать образец CSV из http://explore.data.gov/Energy-and-Utilities/Residential-Energy-Consumption-Survey-RECS-Files-A/eypy-jxs2

#!/usr/bin/env python 

import tempfile 
import shutil 


def main(): 
    f = open('RECS05alldata.csv') 
    data = f.read() 
    f.close() 

    f = open('temp1.csv', 'w+b') 
    f.write(data) 
    f.close() 

    temp = tempfile.NamedTemporaryFile() 
    temp.write(data) 
    shutil.copy(temp.name, 'temp2.csv') 
    temp.close() 

if __name__ == '__main__': 
    main() 

ответ

8

Добавить temp.flush() после temp.write (данные).

+1

Это сработало, но кажется немного противоречивым. Кажется, что temp.flush() должен идти до temp.write (data) в моем сознании. Это то, что я пробовал раньше, и это не сработало. Хотелось бы я лучше понять, почему это работает, чтобы поместить его после write(). – Brent

1

Скопируйте файл, прежде чем закрыть его. Файлы буферизуются, что означает, что некоторые из них будут оставаться в буфере, пока он ждет записи в файл. close выведет все оставшиеся данные из буфера в файл как часть закрытия файла.

Это не имеет никакого отношения к NamedTemporaryFile.

+0

Или [flush()] (http://docs.python.org/library/stdtypes.html#file.flush) в тех случаях, когда вы еще не хотите, чтобы файл был закрыт, но хотите, чтобы данные записывались вне. –

+0

@BrendanLong, вы, как правило, не хотите копировать файл, пока не закончите с ним, но ваша точка верна. –

+0

Python 2.6+ имеет параметр 'delete = True' для этого метода:« Если delete является истинным (по умолчанию), файл удаляется, как только он закрывается » Это может сбить с толку, если вы предполагаете, что это ведет себя одинаково как метод 'open()' и инстинктивно 'close()' 'NamedTemporaryFile', прежде чем копировать его, потому что он исчезнет, ​​и копия будет ошибкой. 'flush()' является решением здесь. – Davos

0

Я думаю, ваша проблема в том, что Python не удалил весь файл на диск, когда вы вызываете shutil.copy.

Изменить

temp = tempfile.NamedTemporaryFile() 
temp.write(data) 
shutil.copy(temp.name, 'temp2.csv') 
temp.close() 

в

temp = tempfile.NamedTemporaryFile() 
temp.write(data) 
temp.close() 
shutil.copy(temp.name, 'temp2.csv') 
+0

Это не будет работать на Python2.6 +, см. Параметр 'delete' https://docs.python.org/2/library/tempfile.html#tempfile.NamedTemporaryFile – Davos

Смежные вопросы