Add new file into the storage.

        Args:
            file_obj (file): Opened file-like object.

        Returns:
            obj: Path where the file-like object is stored contained with hash\
                 in :class:`.PathAndHash` object.

        Raises:
            AssertionError: If the `file_obj` is not file-like object.
            IOError: If the file couldn't be added to storage.

def add_file(self, file_obj):
        """
        Add new file into the storage.

        Args:
            file_obj (file): Opened file-like object.

        Returns:
            obj: Path where the file-like object is stored contained with hash\
                 in :class:`.PathAndHash` object.

        Raises:
            AssertionError: If the `file_obj` is not file-like object.
            IOError: If the file couldn't be added to storage.
        """
        BalancedDiscStorage._check_interface(file_obj)

        file_hash = self._get_hash(file_obj)
        dir_path = self._create_dir_path(file_hash)

        final_path = os.path.join(dir_path, file_hash)

        def copy_to_file(from_file, to_path):
            with open(to_path, "wb") as out_file:
                for part in self._get_file_iterator(from_file):
                    out_file.write(part)

        try:
            copy_to_file(from_file=file_obj, to_path=final_path)
        except Exception:
            os.unlink(final_path)
            raise

        return PathAndHash(path=final_path, hash=file_hash)