python - os.listdir() 使用什么方法获取目录中的文件列表?

标签 python list arraylist directory filenames

我正在开发一个项目,我必须编辑大约 400 个不同文件中的几行内容。它们都在同一个文件夹中,并且每个都有唯一的名称。为了这个问题,我将它们称为fileName001.conffileName420.conf .

我使用 python 脚本来获取每个文件的内容,然后再以编程方式进行编辑。目前,我正在使用此代码片段来获取包含一些 print() 的文件。用于调试的行:

folderPath = '/file/path/to/list/of/conf/files'

for filename in os.listdir(folderPath):
  print('filename = ' + filename)
  print('filepath = ' + folderPath + '/' + filename)

  with open(folderPath + '/' + filename, 'r') as currFile:
    #... code goes on...

第 4 行和第 5 行仅设计用于调试。运行这个,我注意到脚本表现出一些奇怪的行为 - 文件名的打印顺序似乎在每次运行时都会改变。我更进一步并添加了这一行:

print(os.listdir(folderPath))

在我的第一个代码片段中的 for 循环之前。现在,当我从终端运行脚本时,我可以确认我得到的输出虽然包含所有文件名,但每次都有不同的顺序:

RafaGuillermo@virtualMachine:~$ python renamefiles.py
['fileName052.txt', 'fileName216.txt', 'fileName084.txt', 'fileName212.txt', 'fileName380.txt', 'fileName026.txt', 'fileName119.txt', etc...]

RafaGuillermo@virtualMachine:~$ python renamefiles.py
['fileName024.txt', 'fileName004.txt', 'fileName209.txt', 'fileName049.txt', 'fileName166.txt', 'fileName198.txt', 'fileName411.txt', etc...]

RafaGuillermo@virtualMachine:~$

就克服这个问题而言 - 因为我想确保每次都以相同的顺序浏览文件,所以我可以使用

list = sorted(os.listdir(folderPath))

这是列表的字母表,尽管 os.listdir() 似乎违反直觉。每次运行脚本时都会以不同的顺序返回文件名列表。

因此,我的问题是不是如何使用 os.listdir() 获取目录中文件的排序列表,但是:

什么方法os.listdir()用于检索文件列表,为什么它似乎在每次调用时以不同的方式填充其返回值?

最佳答案

答案:

这是 os.listdir() 方法的预期行为。

更多信息:

根据Python Software Foundation Documentation :

os.listdir(path='.')

Return a list containing the names of the entries in the directory given by path. The list is in arbitrary order, and does not include the special entries '.' and '..' even if they are present in the directory.

os.listdir() 是 C 模块的实现,位于 posixmodule.c of the Python source 。返回基于存储文件的文件系统的结构,并且根据确定本地操作系统的条件语句的评估而具有不同的实现。您在 os.listdir() 中调用的目录是使用以下 C 代码打开的:

static PyObject *
_posix_listdir(path_t *path, PyObject *list) {
    /* stuff */
    dirp = opendir(name);

它打开存储在 name 中的目录名称的流,并返回指向目录流的指针以及第一个目录条目的位置。

继续:

for (;;) {
    errno = 0;
    Py_BEGIN_ALLOW_THREADS
    ep = readdir(dirp);
    Py_END_ALLOW_THREADS
    if (ep == NULL) {
        if (errno == 0) {
            break;
        } else {
            Py_DECREF(list);
            list = path_error(path);
            goto exit;
        }
    }
    if (ep->d_name[0] == '.' &&
        (NAMLEN(ep) == 1 ||
         (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
        continue;
    if (return_str)
        v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
    else
        v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
    if (v == NULL) {
        Py_CLEAR(list);
        break;
    }
    if (PyList_Append(list, v) != 0) {
        Py_DECREF(v);
        Py_CLEAR(list);
        break;
    }
    Py_DECREF(v);
}

readdir() 被调用,之前分配的指向目录文件流的指针作为函数参数传递。 readdir()在 Linux 上返回 dirent structure它表示 dirp 指向的目录流中的下一个点。

readdir() Linux 手册页中所述:

A directory stream is opened using opendir(3). The order in which filenames are read by successive calls to readdir() depends on the filesystem implementation; it is unlikely that the names will be sorted in any fashion.

因此,这种行为是预期的,也是文件系统实现的结果。

引用文献:

关于python - os.listdir() 使用什么方法获取目录中的文件列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57555031/

相关文章:

python - Numpy:根据值的顺序将数组分成几部分

Python sys.argv 列表和索引

python - 在 Python 中对两个列表进行相减和相加而不改变它们的顺序

python - 按赢家/输家名称查询体育数据的数据框,并获取每个玩家的汇总统计表?

java - 如何在 Java 中循环遍历 ArrayList 并检查它是否包含另一个 ArrayList 中的值

用于随机数生成的 Python pycrypto 库与 os.urandom

Python:合并 str.contains 并合并到 pandas

list - 如何在knockout.js中制作按钮而不是项目

java - 将 2d 数组列表添加到 3d 数组列表

java - 从 ArrayList 中删除特定条目