zoukankan      html  css  js  c++  java
  • 在web上逐行输出较大的txt文件

    在某些场景下,需要在web上展示一些日志文件,这些日志文件是放在文件服务器上的一些txt。

    当日志文件很大时,下载日志会导致页面长时间卡住,一直在loading状态,而且下载完日志之后分析日志并生成dom,瞬间大量的dom渲染可能导致页面崩溃。

    于是想着优化一下日志的输出方式,开始下载即在页面上一行一行打印日志,就像一些IDE中输出程序的编译过程一样。

    最终实现的方法如下:

    在下载文件的时候,让请求过一层代理,代理写输出流的时候分段输出:

    int l;
            byte[] buffer = new byte[100];
            string llength = "";
            int lsum = 0;
            do
            {
                l = proxyResponseStream.Read(buffer, 0, buffer.Length);
                llength += "," + l;
                lsum += l;
                if (l > 0)
                {
                    context.Response.Write(System.Text.Encoding.UTF8.GetString(buffer, 0, l));
                    context.Response.Flush();
                }
            }
            while (l > 0);
            context.Response.End();

    客户端请求:

    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.onreadystatechange = function (e) {
                    if (this.readyState == 3) {
                        //alert(1);
                        var newload = e.target.responseText.slice(logs[type].length);
                        var newloadLogs = newload.split('
    ');
                        newloadLogs.forEach(function (line, index) {
                            if (index == newloadLogs.length - 1) return;
                            logs[type] += line + '
    ';
                            $("#" + type).append("<p class='logline " + getLogType(line) + "'>" + line + "</p>");
                            document.body.scrollTop = document.body.scrollHeight;
                        });
                    }
                };
                xhr.onload = function () {
                    if (callback) callback();
                }
                xhr.send();
    onreadystatechange

    response多次输出值时,readystate一直是3,onreadystatechange事件可以被多次触发,。

    这样确实可以实现上面所说,无需等待直接开始逐行打印日志。

    但是在实现的过程中发现了这样一些问题

    1.response对象在向客户端写输出流的时候,自己也是有设置一个类似buffer的东西的,只不过这个buffer尺寸很大,对于一般的txt,就算捕获了readystatechange事件,也感觉不出来是在分段输出。当buffer的尺寸被手动设小,满了直接flush的时候,就可以看到日志一小段一小段的打印出来了。不幸的是,这样会大大降低文件被下载的速度,并且占用大量系统资源,失去了优化日志展现的初衷。

    2.response在一段一段输出文件内容的时候,在readystatechange事件中并不能获得每一段输出的值,而是把新输出的内容不断往已输出内容后边append。这样要一段一段解析dom,就需要不断的去记录位置、截取字符串,这样对浏览器来说是一个巨大的消耗。

    3.我拿一个30M大小的txt在本机上测试,开始输出日志后CPU占用瞬间到90%,输出大约一半后浏览器崩溃...

    所以最终得出的结论是:这种方式只能作为日志文件不大的情况下,对交互体验的一种优化,且需要消耗大量系统资源。浏览器中不适合直接展示比较大的txt,它长时间的下载等待以及对浏览器造成的巨大压力是无法优化的,要么分段查看,要么下载后查看或者对其作分析后展现结果。

  • 相关阅读:
    107. Binary Tree Level Order Traversal II
    103. Binary Tree Zigzag Level Order Traversal
    102. Binary Tree Level Order Traversal
    690. Employee Importance
    1723. Find Minimum Time to Finish All Jobs
    LeetCode 329 矩阵中最长增长路径
    7.2 物理内存管理
    LeetCode 面试题 特定深度节点链表
    LeetCode 100 相同的树
    npm安装包命令详解,dependencies与devDependencies实际区别
  • 原文地址:https://www.cnblogs.com/tzyy/p/3816546.html
Copyright © 2011-2022 走看看