JS幻想 读取二进制文件第2/2页

 更新时间:2009年04月20日 15:25:34   作者:  
如果说让JavaScript读取站点上一文本文件,那不过是个再简单不了的事了;但若说要换成一个二进制的文件,并且是完全静态的读取,那似乎有点天方夜谭了。

编码程序虽不复杂,不过也不是几句就能搞定的,为方面这里给个ASP版本的(运行效率非常低,不过处理小文件还是很快的)。JavaScript的解码程序倒是非常的简短,放在Demo.html里一起贴出了。
JSBin.asp:
复制代码 代码如下:

<%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>
<%Option Explicit%>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>JSBin</title>
</head>

<body>
<%
'==================================================
' 类: Stream
'==================================================
Const adTypeBinary = 1
Const adLongVarBinary = 205
Const adSaveCreateOverWrite = 2

Class Stream
    Dim bytBuffer
    Dim lngSize
    Dim lngOffset

    '==================================================
    ' 方法: Load
    ' 说明: 从文件载入数据流
    '==================================================
    Public Function Load(Path)
        Dim objADOStream
        Dim binData
        Dim i

        Set objADOStream = Server.CreateObject("ADODB.Stream")

        With objADOStream
            .Type = adTypeBinary
            .Open
        End With

        With objADOStream
            .LoadFromFile Path
            binData = .Read
            .Close
        End With

        Set objADOStream = Nothing

        lngSize = Ubound(binData)
        ReDim bytBuffer(lngSize)
        lngOffset = 0

        '
        ' 读取数据
        '
        For i = 0 To lngSize
            bytBuffer(i) = AscB(MidB(binData, i + 1, 1))
        Next

        lngSize = lngSize + 1
    End Function

    '==================================================
    ' 方法: Save
    '==================================================
    Public Function Save(Path)
        Dim objADOStream
        Dim objRS
        Dim i
        Dim binData

        Set objADOStream = Server.CreateObject("ADODB.Stream")
        Set objRS = Server.CreateObject("ADODB.Recordset")

        '
        ' ASP处理二进制只能如此
        '
        For i = 0 To lngSize - 1
            binData = binData & ChrB(bytBuffer(i))
        Next

        With objRS
            .Fields.Append "t", adLongVarBinary, lngSize
            .Open
            .AddNew
            .Fields("t").AppendChunk binData
            .Update
            binData = .Fields("t").GetChunk(lngSize)
        End With

        With objADOStream
            .Type = adTypeBinary
            .Open
            .Write binData
            .SaveToFile Path, adSaveCreateOverWrite
            .Close
        End With

        Set objADOStream = Nothing
        Set objRS = Nothing
    End Function

    '==================================================
    ' 方法: Seek
    ' 说明: 定位字节流当前位置
    '==================================================
    Public Function Seek(pos)
        lngOffset = pos
    End Function

    '==================================================
    ' 方法: Read
    '==================================================
    Public Function ReadByte()
        ReadByte = bytBuffer(lngOffset)
        lngOffset = lngOffset + 1    
    End Function


    '==================================================
    ' 方法: WriteUInt
    '==================================================
    Public Function WriteUInt(Code)
        bytBuffer(lngOffset) = CByte(Code Mod 256)
        bytBuffer(lngOffset + 1) = CByte(Code \ 256)

        lngOffset = lngOffset + 2
    End Function



    '==================================================
    ' 属性: Size
    '==================================================
    Public Property Get Size()
        Size = lngSize
    End Property

    Public Property Let Size(value)
        lngSize = value

        ReDim Preserve bytBuffer(lngSize - 1)
    End Property
End Class




'==================================================
' 类: Vector
'==================================================
Const DEFAULT_SIZE = 20
Const NUM_INC = 50

Class Vector
    Dim arrContainer()
    Dim lngSize
    Dim lngCount

    '==================================================
    ' 过程: 类构造
    '==================================================
    Private Sub Class_Initialize()
        lngCount = 0
        lngSize = DEFAULT_SIZE
        ReDim arrContainer(DEFAULT_SIZE - 1)
    End Sub

    Private Sub Class_Terminate()

    End Sub

    '==================================================
    ' 属性: Add
    '==================================================
    Public Function Add(value)
        If lngCount = lngSize Then
            lngSize = lngSize + NUM_INC
            ReDim Preserve arrContainer(lngSize)
        End If

        arrContainer(lngCount) = value
        lngCount = lngCount + 1
    End Function

    '==================================================
    ' 属性: Item
    '==================================================
    Public Property Get Item(id)
        Item = arrContainer(id)
    End Property

    '==================================================
    ' 属性: Count
    '==================================================
    Public Property Get Count()
        Count = lngCount
    End Property
End Class



'==================================================
' 函数: JSBin
' 说明: 将制定的文件转换为JS兼容的二进制文件
' EtherDream 08/06/10
'==================================================
Function JSBin(FileIn, FileOut)
    Const USHRT_MAX = 65536

    Dim objStream
    Dim lngFileLen
    Dim lngSize
    Dim intBuffer()

    Dim Table(65535)
    Dim intVal

    Dim vctKey
    Dim vctZero
    Dim intKeyNum
    Dim intKeyVal

    Dim i

    '
    ' 建立脚本字节流对象
    '
    Set objStream = New Stream

    Set vctKey = New Vector
    Set vctZero = New Vector

    '
    ' 载入文件
    '
    objStream.Load FileIn

    lngFileLen = objStream.Size
    lngSize = (lngFileLen - 1) \ 2

    '
    ' 将字节流转换为整型数组
    '
    ReDim intBuffer(lngSize)

    On Error Resume Next
    With objStream
        For i = 0 To lngSize
            intVal = .ReadByte()
            intVal = intVal + .ReadByte() * 256

            intBuffer(i) = intVal
        Next
    End With
    On Error Goto 0

    '
    ' 计数器清零
    '
    Table(0) = USHRT_MAX

    For i = 1 To USHRT_MAX - 1
        Table(i) = 0
    Next

'
' 统计每个Unicode字符出现的次数(\0\0除外)
'
    With vctZero
        For i = 0 To lngSize
            intVal = intBuffer(i)

            If intVal = 0 Then
                .Add i
            Else
                Table(intVal) = Table(intVal) + 1
            End If
        Next
    End With

'
' 寻找出现次数最少的Unicode
'
    intKeyNum = USHRT_MAX

    For i = 0 To USHRT_MAX - 1
        intVal = Table(i)

        If intVal < intKeyNum Then
            intKeyNum = intVal
            intKeyVal = i
        End If

'
' 发现从未出现过的字符直接完成
'
        If intKeyNum = 0 Then
            Exit For
        End If
    Next

    '
    ' 寻找并记录整型数组中所有intKeyVal的位置
    '
    If intKeyNum > 0 Then
        With vctKey
            For i = 0 To lngSize
                If intBuffer(i) = intKeyVal Then
                    .Add i
                End If
            Next
        End With
    End If


    '
    ' 将整型数组中的0替换为intKeyVal
    '
    With vctZero
        For i = 0 To .Count - 1
            intBuffer(.Item(i)) = intKeyVal
        Next
    End With

    Dim pos

    '
    ' 生成目标文件
    '
    With objStream
        .Size = 6 + intKeyNum * 4 + (lngSize + 1) * 2
        .Seek 0

        .WriteUInt 65279                    'Unicode文件头 0xFEFF
        .WriteUInt intKeyVal                '出现最少的Unicode值    (0已排除)
        .WriteUInt intKeyNum + 1            '出现最少的Unicode次数 (避免0)

        For i = 0 To intKeyNum    - 1            '记录每个最少值的出现位置
            pos = vctKey.Item(i)
            .WriteUInt (pos MOD 65535) + 1    '(避免0)
            .WriteUInt (pos \ 65535) + 1    '(避免0)
        Next

        For i = 0 To lngSize
            .WriteUInt intBuffer(i)
        Next

        '
        ' 保存数据至文件
        '
        .Save FileOut

        Response.Write "转换完成!<br>保存至 " & FileOut & "<br>源文件: " & lngFileLen & "字节.<br>转换后: " & .Size & "字节."
    End With

    Set objStream = Nothing
    Set vctZero = Nothing
    Set vctKey = Nothing
End Function


Sub Main()
    Dim strFile
    Dim strFileIn
    Dim strFileOut

    strFile = Request.QueryString("path")
    strFileIn = Server.MapPath(strFile)
    strFileOut = Server.MapPath(strFile & ".txt")

    JSBin strFileIn, strFileOut
End Sub

Main
%>
</body>
</html>


使用时加上path参数即可对指定的文件编码,比如JSBin.asp?path=123.rar,就会对123.rar编码,并生成123.rar.txt的文件.
客户端的可以在我的空间上预览:
http://www.etherdream.com/FunnyScript/JSBin/JSBinDemo.html
可以在里面输入 JSBin.rar.txt,123.jpg.txt,jsmin.exe.txt即对相应的编码文件加载,所显示的内容与编码前的文件一模一样.对一个二进制的文件仅仅做了几个字节的修改,就能让JavaScript读取,不是很有趣吗?

相关文章

  • javascript读取xml实现javascript分页

    javascript读取xml实现javascript分页

    这篇文章主要介绍了javascript读取xml数据对其实现javascript分页效果,大家参考使用吧
    2013-12-12
  • layer.msg()去掉默认时间,实现手动关闭的方法

    layer.msg()去掉默认时间,实现手动关闭的方法

    今天小编就为大家分享一篇layer.msg()去掉默认时间,实现手动关闭的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-09-09
  • TypeScript中的类型断言[as语法|<>语法]的使用

    TypeScript中的类型断言[as语法|<>语法]的使用

    本文主要介绍了TypeScript中的类型断言[as语法|<>语法]的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • 在 webpack 中使用 ECharts的实例详解

    在 webpack 中使用 ECharts的实例详解

    这篇文章主要介绍了在 webpack 中使用 ECharts的实例代码,需要的朋友可以参考下
    2018-02-02
  • three.js 将图片马赛克化的示例代码

    three.js 将图片马赛克化的示例代码

    这篇文章主要介绍了three.js 将图片马赛克化的方法,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-07-07
  • javascript tips提示框组件实现代码

    javascript tips提示框组件实现代码

    一个简单的类似title的提示效果,但现实内容可以很丰富,以上js另存为tip.js,下面是使用的demo。
    2010-11-11
  • 常用javascript表单验证汇总

    常用javascript表单验证汇总

    这篇文章主要介绍了一些常用javascript表单验证,文章最后还附带了一个实践案例,以验证数字为例进行讲解,感兴趣的小伙伴们可以参考一下
    2015-11-11
  • 原生JS实现的双色球功能示例

    原生JS实现的双色球功能示例

    这篇文章主要介绍了原生JS实现的双色球功能,涉及javascript随机数生成及数值运算相关操作技巧,需要的朋友可以参考下
    2018-02-02
  • 微信小程序利用Canvas绘制图片和竖排文字详解

    微信小程序利用Canvas绘制图片和竖排文字详解

    这篇文章主要介绍了微信小程序利用Canvas绘制图片和竖排文字详解,合成图片应该按照 Canvas 的文档来做都没什么问题,主要是有个竖排文字的需求,这里和大家分享一下,需要的朋友可以参考下
    2019-06-06
  • 深入理解JavaScript中async/await的错误处理方式

    深入理解JavaScript中async/await的错误处理方式

    在现代JavaScript开发中,异步编程是不可或缺的一部分,async和await是一种强大的异步编程工具,它们使得编写和维护异步代码更加容易和清晰,然而,异步操作仍然可能会出现错误,本文将深入探讨async和await的错误处理方式,提供详细的代码示例和解释
    2023-09-09

最新评论