def jkeys(jfile, key_path=None, in_memory=True, ignore_prefix=('.', '_')):
    """ get keys for initial json level, or at level after following key_path

    Parameters
    ----------
    jfile : str, file_like or path_like
        if str, must be existing file or folder,
        if file_like, must have 'read' method
        if path_like, must have 'iterdir' method (see pathlib.Path)
    key_path : list[str]
        a list of keys to index into the json before returning keys
    in_memory : bool
        if true reads json into memory before finding keys
        (this is faster but uses more memory)
    ignore_prefix : list[str]
        ignore folders beginning with these prefixes

    Examples
    --------

    >>> from jsonextended.utils import MockPath
    >>> file_obj = MockPath('test.json',is_file=True,
    ... content='''
    ... {
    ...  "a": 1,
    ...  "b": [1.1,2.1],
    ...  "c": {"d":"e","f":"g"}
    ... }
    ... ''')
    ...
    >>> jkeys(file_obj)
    ['a', 'b', 'c']

    >>> jkeys(file_obj,["c"])
    ['d', 'f']

    >>> from jsonextended.utils import get_test_path
    >>> path = get_test_path()
    >>> jkeys(path)
    ['dir1', 'dir2', 'dir3']

    >>> path = get_test_path()
    >>> jkeys(path, ['dir1','file1'], in_memory=True)
    ['initial', 'meta', 'optimised', 'units']

    """
    key_path = [] if key_path is None else key_path

    def eval_file(file_obj):
        if not in_memory:
            return _get_keys_ijson(file_obj, key_path)
        else:
            return _get_keys(file_obj, key_path)

    if isinstance(jfile, basestring):
        if not os.path.exists(jfile):
            raise IOError('jfile does not exist: {}'.format(jfile))
        if os.path.isdir(jfile):
            jpath = pathlib.Path(jfile)
            return _get_keys_folder(jpath, key_path, in_memory, ignore_prefix)
        else:
            with open(jfile, 'r') as file_obj:
                return eval_file(file_obj)
    elif hasattr(jfile, 'read'):
        return eval_file(jfile)
    elif hasattr(jfile, 'iterdir'):
        if jfile.is_file():
            with jfile.open('r') as file_obj:
                return eval_file(file_obj)
        else:
            return _get_keys_folder(jfile, key_path, in_memory, ignore_prefix)
    else:
        raise ValueError(
            'jfile should be a str, '
            'file_like or path_like object: {}'.format(jfile))