简体   繁体   中英

Write a file to disk only when first content is written into it

I open a file with :

mylog = open('test.log', 'w')

and sometimes some content is written in mylog during the running time of my application ; but sometimes nothing is written during the running time of the app, it depends.

In both cases, it seems that the file test.log is always created on disk.

Is there a way of writing the file to disk only when the first content is written into it ? (with something like mylog.write('blah') for example)

ie if mylog.write('...') is never called, then the (empty) file test.log is not created on disk.

Create your own file wrapper class, storing a file object. It needs the following methods to work with context managers and normal close function

class MyFile():
    def __enter__(self):
        return self

    def __init__(self, path, *args):
        ''' store the path, but don't actually open the file '''
        self.path = path
        self.file_object = None
        self.args = args

    def write(self, s):
        ''' you open the file here, just before writing '''
        if not self.file_object:
            self.file_object = open(self.path, *self.args)
        self.file_object.write(self, s)

    def close(self):
        ''' close the file '''
        if self.file_object:
            self.file_object.close()

    def __exit__(self, exc_type, exc_value, exc_traceback):
        self.close()

You can either use a context manager to open/close:

with MyFile('test.log', 'w') as mylog:
    mylog.write('...')

Or the classic way, calling the functions directly:

mylog = MyFile('test.log', 'w')
mylog.write('...')
mylog.close()

You'll have to create a wrapper object that'll only actually open the file when the first write() is called:

class DelayedFile(object):
    fileobj = None

    def __init__(self, filename, *args, **kw):
        self.filename = filename
        self.args = args
        self.kw = kw

    def write(self, data):
        if self.fileobj is None:
            self.fileobj = open(self.filename, *self.args, **self.kw)
        return self.fileobj.write(data)

    def close(self):
        if self.fileobj is not None:
            return self.close() 

    def __enter__(self):
        return self

    def __exit__(self, *args, **kw):
        if self.fileobj is not None:
            return self.fileobj.__exit__(*args, **kw)

Note that this has some disadvantages; any I/O errors on opening are not going to be raised until that first write() call.

The above proxy object implements only a subset of the standard file object API ; you can add more methods as needed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM