2013-05-11 2 views
2

Comment enregistrer un message électronique dans un fichier sans le charger dans la mémoire? J'utiliseComment enregistrer un message électronique dans un fichier sans le charger dans la mémoire?

import poplib 
pop_conn = poplib.POP3(servername) 
pop_conn.user(username) 
pop_conn.pass_(passwd) 
msg = pop_conn.retr(msg_number)[1] 
msg_text = '\n'.join(msg) 
msg_file = open(msg_file_name, ,"wb") 
msg_file.write(msg_text) 
msg_file.close() 

Mais message chargé en mémoire.

+2

Vous ne pouvez pas? Toutes les opérations en Python sont essentiellement X-> Mémoire tampon-> Disque .. – Torxed

+0

Je pense qu'il faut regarder dans le sens de la programmation socket. Mais je ne sais pas exactement comment le faire. – agrynchuk

+0

encore, 'socket' ->' memory buffer' -> 'disk' .. même chose là-bas. Du point de vue de l'assemblage, tout est avant tout le calcul du processeur et de la mémoire. Ce dont il s'agit essentiellement, c'est de déplacer les allocations de mémoire petit à petit et de dire au CPU d'aller chercher de la mémoire dans d'autres parties de la carte mère (par exemple, le disque). Vous ne pouvez pas venir autour de la mémoire .. Je suis désolé .. – Torxed

Répondre

0

Le python documente caution contre l'utilisation du protocole POP3. Votre serveur de messagerie comprend probablement IMAP, vous pouvez donc utiliser IMAP4.partial() pour récupérer le message en parties, en écrivant chaque partie sur le disque immédiatement.

Mais si vous avez pour utiliser POP3, vous avez de la chance: Le protocole POP3 est orienté ligne. La bibliothèque poplib de Python est pure python, et il est trivial d'ajouter un itérateur en regardant the source. Je ne l'ai pas pris la peine de dériver de la classe POP3, voici donc comment le faire par singe-patching:

from poplib import POP3 

def iretr(self, which): 
    """ 
    Retrieve whole message number 'which', in iterator form. 
    Return content in the form (line, octets) 
    """  
    self._putcmd('RETR %s' % which) 
    resp = self._getresp() # Will raise exception on error 

    # Simplified from _getlongresp() 
    line, o = self._getline() 
    while line != '.': 
     if line[:2] == '..': 
      o = o-1 
      line = line[1:] 
     yield line, o 
     line, o = self._getline() 

POP3.iretr = iretr 

Vous pouvez alors chercher votre message et écrire sur le disque d'une ligne à la fois, comme celui-ci:

pop_conn = POP3(servername) 
... 
msg_file = open(msg_file_name, "wb") 
for line, octets in pop_conn.iretr(msg_number): 
    msg_file.write(line+"\n") 
msg_file.close() 
+0

Merci pour le conseil mais j'en ai besoin pour utiliser le protocole pop3 – agrynchuk

+0

@agry, voir la réponse révisée. – alexis

Questions connexes