如何在Fuse python中正确编写readdir?

时间:2014-02-03 21:35:32

标签: python fuse

我想学习如何在Fuse中编写文件系统。我的想法是编写一个与pinboard.in(书签服务)通信的文件系统。我有readdir的问题。据我所知(这不是很多,因为这对我来说是新的东西)readdir是返回文件系统中文件和文件夹的函数。

我有以下代码:

def readdir ( self, path, flags ):
    print '*** readdir', path, flags
    if path == '/':
        # Path is root meaning we need to list tags and untagged bookmarks
        tags_json=urllib2.urlopen('https://api.pinboard.in/v1/tags/get?format=json&auth_token='+self.apitoken).read()
        tags = json.loads(tags_json)
        ret = map(lambda k: fuse.Direntry(name=k, type=stat.S_IFDIR), tags.keys())
        print ret
        return ret
    else:
        pass

当使用调试标志在Fuse中运行时,我得到类似

的内容
    *** getattr /
    unique: 2, success, outsize: 120
    unique: 3, opcode: OPENDIR (27), nodeid: 1, insize: 48, pid: 6441
    unique: 3, success, outsize: 32
    unique: 4, opcode: READDIR (28), nodeid: 1, insize: 80, pid: 6441
    readdir[0] from 0
    *** readdir / 0
    [<fuse.Direntry object at 0xb65b8f70>, <fuse.Direntry object at 0xb65b8f90>,........,<fuse.Direntry > object at 0xb65e1670>]
    unique: 4, success, outsize: 16
    unique: 5, opcode: RELEASEDIR (29), nodeid: 1, insize: 64, pid: 0
    unique: 5, success, outsize: 16

但文件系统为空。我尝试了一切,但我认为我不理解文件系统的流程。我真正的问题是,我该返回什么,所以ls显示文件/目录?我应该在哪里阅读这个?

如果您需要更多代码,可以访问我的bitbucket并阅读所有内容:https://bitbucket.org/aquaplanet/pinboard.in-fuse/commits/38212eb035d3aba163bab9ed5a6b9284ce1dc93c

非常感谢您抽出时间阅读我的问题,我期待着您的回答!

解决方案

感谢@aleatha,他告诉我我写的正确但是在tags.keys()中有一种类型错误,正常的字符串有效,我很快发现tags.keys()是unicode。尽管在LANG和LC_CTYPE(处理覆盆子pi)中都有sv_SE.UTF-8,但它需要8位字符串。这样做效果更好:

def readdir ( self, path, flags ):
    print '*** readdir', path, flags
    if path == '/':
        # Path is root meaning we need to list tags and untagged bookmarks
        tags_json=urllib2.urlopen('https://api.pinboard.in/v1/tags/get?format=json&auth_token='+self.apitoken).read()
        tags = json.loads(tags_json)
        ret = map(lambda k: fuse.Direntry(name=k.encode('iso-8859-1','replace'), type=stat.S_IFDIR), tags.keys())
        return ret
    else:
        pass

1 个答案:

答案 0 :(得分:4)

你看起来像是在正确的道路上......你需要返回一系列的Direntry对象。

如果我用简单的字符串数组替换你的API调用,例如:

tags = ["a", "b", "c"]  
ret = map(lambda k: fuse.Direntry(name = k, type = stat.S_IFDIR), tags)
return ret

然后它工作正常。所以我的猜测是tags.keys()有问题。我首先检查各个Direntry对象,看看它们是否正确。