def _prepare_openers(self): # Saved openers self._opener = dict() # Locks (still unsure why I need that) self._lock = dict() for key, val in self._image.file_map.items(): mode = self.mode + 'b' # everything is binary in nibabel (?) file_like = val.file_like self._lock[key] = RLock() if hasattr(file_like, 'read') and hasattr(file_like, 'seek'): # file object -> keep stuff irrelevant if not file_like.readable() or not file_like.seekable(): raise ValueError('File must be readable and seekable') if '+' in self.mode and not file_like.writable(): raise ValueError('File must be writable in mode "r+"') self._opener[(key, self.mode)] = file_like continue if self.keep_open: try: self._opener[(key, mode)] = open(file_like, mode, keep_open=True) except ValueError: self._opener[(key, mode)] = open(file_like, 'rb', keep_open=True) else: self._opener[(key, 'r')] = open(file_like, 'rb', keep_open=False) if not self._opener[(key, 'r')].is_indexed: del self._opener[(key, 'r')]
def to_filename(self, fname): """Write to file""" with open(fname, 'wt') as f: return self.to_file_like(f)
def from_filename(cls, fname): """Build from path to LTA file""" with open(fname, 'r') as f: return cls.from_lines(f)
def fileobj(self, key='image', mode='', seek=None): """Return an `Opener`. It can be used with: >> nii = BabelArray('/path/to/file') >> with nii.fileobj('image') as f: >> f.seek(pos) >> ... Parameters ---------- key : str, default='image' Key of the file to open mode : {'r', 'r+', 'w', 'w+', 'a', 'a+'}, default='r' Opening mode. The file type ('b' or 't') should be omitted. seek : int, optional Position to seek. """ if key not in self._image.file_map: key = 'image' if not mode: mode = 'r' opener = None # check if we have the right opener if (key, mode) in self._opener: opener = self._opener[(key, mode)] # otherwise, check if we have one with more permissions than needed if opener is None and (key, mode + '+') in self._opener: opener = self._opener[(key, mode + '+')] # otherwise, check if we can hack a liberal one # (e.g., 'r+' -> 'w(+)' or 'a(+)') if opener is None: for (key0, mode0), opener0 in self._opener.items(): if key0 != key: continue try: opener = transform_opener(opener0, mode) break except ValueError: pass # we found one -> perform a few sanity checks if opener is not None: check = True if 'r' in mode or '+' in mode: check = check and opener.readable() if 'w' in mode or 'a' in mode: check = check and opener.writable() if check: if seek is not None: opener.seek(seek) yield opener return # everything failed -> create one from scratch file_map = self._image.file_map[key] with open(file_map.file_like, mode=mode, keep_open=False) as opener: check = True if 'r' in mode or '+' in mode: check = check and opener.readable() if 'w' in mode or 'a' in mode: check = check and opener.writable() if check: if seek is not None: opener.seek(seek) yield opener return raise RuntimeError('Could not yield an appropriate file object')