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,它长时间的下载等待以及对浏览器造成的巨大压力是无法优化的,要么分段查看,要么下载后查看或者对其作分析后展现结果。

  • 相关阅读:
    Python: execute an external program (zz)
    Python notes
    Web Monitor/Dev/Test Tool Collection 网站/网页监控/开发/测试工具集合
    SilkTest 2006 sp2 Notes of GettingStartedTutorial (2008,07)
    Software Testing Essentials 软件测试精要
    Flex notes
    Review Java advanced features
    Fedora 11 Configuration and Management
    进制转换的方法原理
    win32 透明置顶
  • 原文地址:https://www.cnblogs.com/tzyy/p/3816546.html
Copyright © 2011-2022 走看看