牛奶味的巧克力 發表於 2023-8-24 00:00:00

linux中快速列出文件列表的多种方法总结

<p>
        <span><strong>前言</strong></span></p>
<p>
        最近在工作中碰到一个很棘手的问题,需要读取出ubuntu系统中某个目录下所有文件,由于服务器中存储的文件实在太多,导致此过程效率十分低下,动辄需要等待一个小时之久,还只是一个目录。于是如何快速获取文件列表便是这两天的头等大事,折腾半天找到一个较为快速的方法,记录如下,话不多说了,来一起看看详细的介绍吧。</p>
<p>
        <span><strong>多种实现方法</strong></span></p>
<p>
        尝试了多种方法,有编程的和非编程的。</p>
<p>
        <strong>1、walk</strong></p>
<p>
        python的walk库能够递归的读取目录下所有文件,这个是最常规的方法,然而效率有些缓慢。实现很简单,不赘述。</p>
<p>
        <strong>2、os.scandir</strong></p>
<p>
        python中的<code>os.scandir</code>方法官方解释为快速读取目录,测试了一下速度相对walk而言是由提高,但是还是达不到要求,也需要自己写递归,代码如下:</p>
<div class="jb51code">
        <div>
                <div class="syntaxhighlighterpy" id="highlighter_327748">
                        <div class="toolbar">
                                <span>?</span>
</div>
                        <table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
                                                        <div class="line number1 index0 alt2">
                                                                1</div>
                                                        <div class="line number2 index1 alt1">
                                                                2</div>
                                                        <div class="line number3 index2 alt2">
                                                                3</div>
                                                        <div class="line number4 index3 alt1">
                                                                4</div>
                                                        <div class="line number5 index4 alt2">
                                                                5</div>
                                                        <div class="line number6 index5 alt1">
                                                                6</div>
                                                        <div class="line number7 index6 alt2">
                                                                7</div>
                                                        <div class="line number8 index7 alt1">
                                                                8</div>
                                                        <div class="line number9 index8 alt2">
                                                                9</div>
                                                        <div class="line number10 index9 alt1">
                                                                10</div>
                                                </td>
                                                <td class="code">
                                                        <div class="container">
                                                                <div class="line number1 index0 alt2">
                                                                        <code class="py keyword">def</code> <code class="py plain">scan_path(file_path, level </code><code class="py keyword">=</code> <code class="py value">3</code><code class="py plain">):</code>
</div>
                                                                <div class="line number2 index1 alt1">
                                                                        <code class="py spaces"> </code><code class="py plain">files </code><code class="py keyword">=</code> <code class="py plain">[]</code>
</div>
                                                                <div class="line number3 index2 alt2">
                                                                        <code class="py spaces"> </code><code class="py keyword">if</code> <code class="py plain">level &gt;</code><code class="py keyword">=</code> <code class="py value">0</code><code class="py plain">:</code>
</div>
                                                                <div class="line number4 index3 alt1">
                                                                        <code class="py spaces">  </code><code class="py plain">path </code><code class="py keyword">=</code> <code class="py plain">os.scandir(file_path)</code>
</div>
                                                                <div class="line number5 index4 alt2">
                                                                        <code class="py spaces">  </code><code class="py keyword">for</code> <code class="py plain">p </code><code class="py keyword">in</code> <code class="py plain">path:</code>
</div>
                                                                <div class="line number6 index5 alt1">
                                                                        <code class="py spaces">   </code><code class="py keyword">if</code> <code class="py plain">p.is_dir():</code>
</div>
                                                                <div class="line number7 index6 alt2">
                                                                        <code class="py spaces">    </code><code class="py plain">files.extend(scan_path(p.path, level </code><code class="py keyword">-</code> <code class="py value">1</code><code class="py plain">))</code>
</div>
                                                                <div class="line number8 index7 alt1">
                                                                        <code class="py spaces">   </code><code class="py keyword">else</code><code class="py plain">:</code>
</div>
                                                                <div class="line number9 index8 alt2">
                                                                        <code class="py spaces">    </code><code class="py plain">files.append(p.path)</code>
</div>
                                                                <div class="line number10 index9 alt1">
                                                                        <code class="py spaces"> </code><code class="py keyword">return</code> <code class="py plain">files</code>
</div>
                                                        </div>
                                                </td>
                                        </tr></tbody></table>
</div>
        </div>
        <div class="codetool" id="codetool">
                <div class="code_n">
                        <textarea></textarea>
</div>
        </div>
</div>
<p>
        当这两种方法都行不通的时候我就开始考虑才用非编程方法了。理论上来说python的执行效率已经蛮高了,虽然可能达不到c或者c++的速度,但是相比java、C#来说已经够快了,所以就没有再考虑编程的方式,而是转向linux系统原生的方式。</p>
<p>
        <strong>3、ls</strong></p>
<p>
        最先想到的就是ls命令,使用如下命令</p>
<div class="jb51code">
        <div>
                <div class="syntaxhighlighterbash" id="highlighter_832382">
                        <div class="toolbar">
                                <span>?</span>
</div>
                        <table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
                                                        <div class="line number1 index0 alt2">
                                                                1</div>
                                                </td>
                                                <td class="code">
                                                        <div class="container">
                                                                <div class="line number1 index0 alt2">
                                                                        <code class="bash functions">ls</code> <code class="bash plain">–l –R(或-lR) src &gt; list.txt</code>
</div>
                                                        </div>
                                                </td>
                                        </tr></tbody></table>
</div>
        </div>
        <div class="codetool" id="codetool">
                <div class="code_n">
                        <textarea></textarea>
</div>
        </div>
</div>
<p>
        此命令能够列出src目录下的所有文件,但是效率还是不够高,而且结果包含了目录信息以及文件信息,不太整齐,需要后续处理。</p>
<p>
        <strong>4、tree</strong></p>
<p>
        tree命令本身用于列出文件系统的结构树,在设置一些参数的情况下也能够实现列出所有目录和文件的功能。</p>
<div class="jb51code">
        <div>
                <div class="syntaxhighlighterbash" id="highlighter_510585">
                        <div class="toolbar">
                                <span>?</span>
</div>
                        <table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
                                                        <div class="line number1 index0 alt2">
                                                                1</div>
                                                </td>
                                                <td class="code">
                                                        <div class="container">
                                                                <div class="line number1 index0 alt2">
                                                                        <code class="bash plain">tree -afi -L 3 -o 2.txt --noreport src</code>
</div>
                                                        </div>
                                                </td>
                                        </tr></tbody></table>
</div>
        </div>
        <div class="codetool" id="codetool">
                <div class="code_n">
                        <textarea></textarea>
</div>
        </div>
</div>
<p>
        -a列出所有文件,-f列出完整路径(结果为绝对路径或者相对路径与find用法一致),-i不画tree的结构线, -L列出多少层目录,-o输出到文件,--noreport不要最后的summary。</p>
<p>
        <strong>5、find</strong></p>
<p>
        find命令本身是查找文件的命令,但是如果使用得当,能够快速列出目录下文件,命令如下:</p>
<div class="jb51code">
        <div>
                <div class="syntaxhighlighterbash" id="highlighter_731600">
                        <div class="toolbar">
                                <span>?</span>
</div>
                        <table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
                                                        <div class="line number1 index0 alt2">
                                                                1</div>
                                                </td>
                                                <td class="code">
                                                        <div class="container">
                                                                <div class="line number1 index0 alt2">
                                                                        <code class="bash functions">find</code> <code class="bash plain">src &gt; 1.txt</code>
</div>
                                                        </div>
                                                </td>
                                        </tr></tbody></table>
</div>
        </div>
        <div class="codetool" id="codetool">
                <div class="code_n">
                        <textarea></textarea>
</div>
        </div>
</div>
<p>
        此命令速度足够快,基本能够满足需要了。find的结果相对当前src的路径,也就是说其每条结果的开头均是src,如果src为绝对路径,则结果为绝对路径,如果src为相对路径,则结果以此相对路径为开头。</p>
<p>
        <strong>6、locate</strong></p>
<p>
        又Google了一下,发现locate与find的功能相似,locate也能够查找文件,于是猜想locate也能够实现此功能,试之,果然可以,写法都是一样的。</p>
<div class="jb51code">
        <div>
                <div class="syntaxhighlighterbash" id="highlighter_857183">
                        <div class="toolbar">
                                <span>?</span>
</div>
                        <table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
                                                        <div class="line number1 index0 alt2">
                                                                1</div>
                                                </td>
                                                <td class="code">
                                                        <div class="container">
                                                                <div class="line number1 index0 alt2">
                                                                        <code class="bash functions">locate</code> <code class="bash plain">src &gt; 1.txt</code>
</div>
                                                        </div>
                                                </td>
                                        </tr></tbody></table>
</div>
        </div>
        <div class="codetool" id="codetool">
                <div class="code_n">
                        <textarea></textarea>
</div>
        </div>
</div>
<p>
        不同点在于无论src为相对路径还是绝对路径,其结果均为绝对路径。</p>
<p>
        使用time命令进行命令执行时间测试,发现find和locate时间基本相同,有时locate会稍微快一些,而tree命令则有些慢。</p>
<p>
        <span><strong>结论</strong></span></p>
<p>
        以上均可取到文件夹下所有文件,使用walk和scandir最为方便与程序集成,但是速度稍微有些慢,find和locate命令速度较快,tree命令功能强大,但速度相对find和locate有些慢,此三者若要与python集成,则需要在程序中使用os.popen等管道机制来执行拼接的bash命令。所以以上命令各有所长,按照自己的需求取舍。</p>
<p>
        <span><strong>总结</strong></span></p>
<p>
        以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。</p>
<p>
        原文链接:http://www.jianshu.com/p/3a9c1800bce1</p>
頁: [1]
查看完整版本: linux中快速列出文件列表的多种方法总结