You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何让Python http.server显示目录中文件的大小与日期信息?

实现带文件详情的Python HTTP目录服务

嘿,这个需求我刚好折腾过!默认的python -m http.server确实只展示文件名,不过我们可以通过自定义请求处理器来实现你想要的FTP风格文件列表——显示修改日期和文件大小。

核心原理

http.server模块里的SimpleHTTPRequestHandler类负责生成目录页面,它的list_directory方法默认只输出文件名链接。我们只需要重写这个方法,在生成HTML表格时加入文件的修改时间和大小信息即可。

具体实现步骤

  1. 创建一个自定义的服务器脚本,比如命名为custom_http_server.py,内容如下:
import os
import time
from http.server import HTTPServer, SimpleHTTPRequestHandler

def format_file_size(size_bytes):
    """把字节数转换成易读的格式(KB/MB等)"""
    if size_bytes < 1024:
        return f"{size_bytes} B"
    elif size_bytes < 1024**2:
        return f"{size_bytes/1024:.1f} KB"
    elif size_bytes < 1024**3:
        return f"{size_bytes/(1024**2):.1f} MB"
    else:
        return f"{size_bytes/(1024**3):.1f} GB"

class CustomHTTPHandler(SimpleHTTPRequestHandler):
    def list_directory(self, path):
        try:
            list_dir = os.listdir(path)
        except OSError:
            self.send_error(404, "No permission to list directory")
            return None
        
        list_dir.sort(key=lambda a: a.lower())
        r = []
        displaypath = os.path.abspath(path)
        
        # 生成HTML头部
        r.append('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">')
        r.append(f"<html><head><title>Directory listing for {displaypath}</title></head>")
        r.append(f"<body><h1>Directory listing for {displaypath}</h1>")
        r.append("<table><tr><th>Name</th><th>Last Modified</th><th>Size</th></tr>")
        
        # 添加上一级目录链接
        r.append('<tr><td><a href="..">../</a></td><td></td><td></td></tr>')
        
        for name in list_dir:
            fullname = os.path.join(path, name)
            displayname = linkname = name
            # 如果是目录,末尾加/
            if os.path.isdir(fullname):
                displayname = name + "/"
                linkname = name + "/"
            
            # 获取文件信息
            stat_info = os.stat(fullname)
            # 格式化修改时间(本地时间)
            mod_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(stat_info.st_mtime))
            # 格式化文件大小
            file_size = format_file_size(stat_info.st_size) if not os.path.isdir(fullname) else "-"
            
            r.append(f'<tr><td><a href="{linkname}">{displayname}</a></td><td>{mod_time}</td><td>{file_size}</td></tr>')
        
        r.append("</table></body></html>")
        encoded = '\n'.join(r).encode('utf-8', 'surrogateescape')
        f = self.wfile
        self.send_response(200)
        self.send_header("Content-type", "text/html; charset=utf-8")
        self.send_header("Content-Length", str(len(encoded)))
        self.end_headers()
        f.write(encoded)
        return None

if __name__ == '__main__':
    import sys
    port = int(sys.argv[1]) if len(sys.argv) > 1 else 8000
    server_address = ('', port)
    httpd = HTTPServer(server_address, CustomHTTPHandler)
    print(f"Serving HTTP on 0.0.0.0 port {port} (http://0.0.0.0:{port}/) ...")
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        print("\nKeyboard interrupt received, exiting.")
        httpd.server_close()
  1. 运行这个自定义服务器:
# 默认端口8000
python custom_http_server.py

# 指定端口,比如8080
python custom_http_server.py 8080
  1. 现在访问对应的地址,就能看到包含文件名最后修改时间文件大小的列表了,完全是你想要的FTP风格!

小细节说明

  • 这里用的是文件的st_mtime(修改时间),而不是st_ctime,因为st_ctime在Windows下是创建时间,在Linux下是属性变更时间,跨平台的话st_mtime更通用。
  • format_file_size函数把字节转换成了易读的单位,避免直接显示大数字。
  • 目录的大小会显示为-,和FTP的表现一致。

内容的提问来源于stack exchange,提问作者mankand007

火山引擎 最新活动