11
votes

Comment limiter la taille du fichier lors de l'écriture?

J'utilise les flux de sortie du module IO et écrivez aux fichiers. Je veux pouvoir détecter lorsque j'ai écrit 1 g de données dans un fichier, puis commencez à écrire dans un deuxième fichier. Je ne peux pas sembler comprendre comment déterminer la quantité de données que j'ai écrite dans le fichier.

Y a-t-il quelque chose de facile intégré à io ? Ou pourriez-je devoir compter les octets avant chaque écriture manuellement?


0 commentaires

6 Réponses :


3
votes

Voir la méthode Tell () sur l'objet Stream.


0 commentaires

0
votes

Je recommande de compter. Il n'y a pas de compteur de langue interne que je suis au courant. Quelqu'un d'autre a mentionné à l'aide de dell () code>, mais un compteur interne prendra à peu près la même quantité de travail et éliminera les appels constants du système d'exploitation.

#pseudocode
if (written + sizeOfNew > 1G) {
    rotateFile()
}


2 commentaires

Sauf que si vous êtes judicieux avec dell () et permettez une marge d'erreur, c'est beaucoup moins de frais généraux que de compter.


Je ne peux pas imaginer comment cela pourrait être moins aérien. Ajout à un entier et le comparant à une valeur maximale est à la fois des opérations à instruction unique, ou de près de celui-ci si votre type est un peu important. dire () va descendre un arbre d'appel système. En outre, chaque fois que vous dites (), vous vérifiez quelque chose qui a déjà été écrit. Vous pouvez coder pour cela sans trop de problèmes, mais ...



9
votes

Voir la documentation Python pour Objets de fichier , spécifiquement DIT ().

Exemple: P>

>>> f=open('test.txt','w')
>>> f.write(10*'a')
>>> f.tell()
10L
>>> f.write(100*'a')
>>> f.tell()
110L


0 commentaires

16
votes

2 commentaires

Les informations sur la logrotate sont utiles pour comprendre cette approche: debian-administration.org/articles/1174


Besoin d'ajouter ceci: importer la journalisation.HandLers



2
votes

Une approche assez simple consiste à sous-classer la classe de fichier et à garder une trace de la quantité de sortie qui est écrite dans le fichier. Vous trouverez ci-dessous un exemple de code montrant comment cela pourrait être fait qui semble principalement fonctionner.

Je dis principalement parce que la taille des fichiers produits est parfois légèrement sur le maximum, tout en le testant, mais c'est que le fichier test a été ouvert en mode "texte" et sous Windows, cela signifie que tous les \ N ' Les caractères LineFeed sont convertis en ' \ r \ n ' (retour-à-coups, paires de linefeed) qui jette l'accumulateur de taille éteint. En outre, comme actuellement écrit, l'argument bufsize que le fichier standard () et ouvrir () Les fonctions Accepter n'est pas prise en charge, donc la valeur par défaut du système La taille et le mode seront toujours utilisés.

Selon exactement ce que vous faites, la question de taille peut ne pas être un gros problème - cependant, pour de grandes tailles maximales, elle pourrait être de manière significative. Si quelqu'un a une bonne fixation indépendante de la plate-forme, par tous les moyens, laissez-nous savoir. xxx


0 commentaires

1
votes

J'ai remarqué une ambiguïté dans votre question. Voulez-vous que le fichier soit (a) sur (b) sous (c) exactement 1GIB grand, avant de changer?

Il est facile de dire si vous êtes passé. dire () est suffisant pour ce genre de chose; Vérifiez simplement si dites ()> 1024 * 1024 * 1024: et vous saurez.

Vérification si vous êtes sous 1GiB, mais passera sur 1GIB lors de votre prochaines écriture, est une technique similaire. si len (data_to_write) + dit> 1024 * 1024 * 1024: suffira.

La chose la plus difficile à faire est d'obtenir le fichier exactement 1GiB. Vous aurez besoin de dell () la longueur du fichier, puis partitionner vos données de manière appropriée afin de toucher la marque précisément.

Peu importe exactement quelle sémantique que vous souhaitez, dell () va toujours être au moins aussi lent que le comptage vous-même et éventuellement plus lent. Cela ne signifie pas que c'est la mauvaise chose à faire; Si vous écrivez le fichier à partir d'un thread, vous voudrez presque certainement dire () plutôt que d'espoir que vous avez correctement préempté les autres threads écrivant dans le même fichier. (Et faites vos serrures, etc., mais c'est une autre question.)

Au fait, j'ai remarqué une direction définitive dans vos dernières questions. Êtes-vous au courant des chaînes #Twisted et #Python IRC sur freenode (irc.freenode.net)? Vous obtiendrez des réponses plus utiles et plus utiles.

~ c.


0 commentaires