首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VB >

从自各儿的文件读出内嵌其中的二进制文件后,读出来的文件无法使用

2012-12-17 
从自己的文件读出内嵌其中的二进制文件后,读出来的文件无法使用题目很长,希望有心的认真看一下,谢谢了!!我

从自己的文件读出内嵌其中的二进制文件后,读出来的文件无法使用
题目很长,希望有心的认真看一下,谢谢了!!


我自己设计了一种文件,想实现将其他文件的内容嵌入到自己文件的功能。我用二进制方式将需要嵌入的文件读出来,然后接着将读出来的字节数组转成字符串,然后存放入对象的变量里。在要写入的时候直接从属性中读出来,然后写到自己的文件里。自己的文件前面有一些东西,以一个特定的分隔符为记号,作为嵌入二进制数据的开始。同样,在嵌入数据的结束,也有一个标记表示结束。具体代码如下:


    With MemoObject.AutoRemind
    ……
          '分配文件号
            TmpFileNumber = FreeFile
            '打开文件
            Open .FileName For Binary As TmpFileNumber
                '重定义字节数组大小
                ReDim BtFileContent(LOF(TmpFileNumber)) As Byte
                '读取文件
                Get #TmpFileNumber, , BtFileContent
                '字节数组转字符串
                StrFileContent = StrConv(BtFileContent, vbUnicode)
                '比较内容
                If StrFileContent <> .Srouce Then
                    .Srouce = StrFileContent '不同则按照当前文件内容修改
                End If
            Close #TmpFileNumber
            
        Else '非内嵌
            .Srouce = "" '清除属性
         End If
        Put #1, , .Srouce & E_AutoRemind
    End With

MemoObject.AutoRemind就是上面提到对象,这个对象的一些属性保存着内嵌文件的信息,例如原始文件名FileName,还有保存着读出来数据的Srouce。E_AutoRemind是字符串常数,是哪个代表结束的标志。

    现在假设已经有按照上面代码写出来的一个文件。这是下一次运行,文件现在要重新读出来,我就用查找标志的方法,将中间的数据重新读出来,然后再用Open .FileName For Binary As #1再重新写成原来的文件。可是问题就是写出来的文件没用了。
    我做测试的时候开始嵌入的是一个完好的音频文件(是一首歌),可是重新写出来的文件虽然播放器依然认可他是一个音频,可是播放出来的就不是歌了,是一些乱七八糟的噪音。后来我又嵌入一张图片,发现随后写出来的文件虽然也是图片,可是图案已经扭曲变形,不再是原来的东西了。而且发现写出来的文件总是比原来的要小。
    现在,我不懂的是 我用嵌入的时候OPen语句完整地读出来的文件数据,为什么后来再写的时候会少了什么东西呢?其次,写出来的文件也不是说变得完全没用了,如果是中间转换成字符串,这样丢失了二进制数据的某一些特性,那么写出来的文件就应该什么都不是。可是现在写出来的文件音频还是音频,图像还是图像;播放器,图片查看器都不会提示这是一个不符合要求的文件,只是播出来的音乐不对了,显示出来的图片也不对了。这就更不懂了

[最优解释]
设计错误:

1) StrConv() 能对纯文本内容在 ANSI 和 Unicode 之间转换,不能用于非文本内容(音频、图像等)。
要么直接打包二进制内容、要么用 Base-64 编码进行转换。

2)你不能保证所用的“结束标志”不出现在文件内容当中,解包时会导致不正确的分割。
采用前缀长度的方案,解包时不需搜索可以直接按长度分割。
[其他解释]
音频,图像,都有固定格式,比如WAV吧,文件长度,数据长度都在头部标注了,如果你少写或少读了一些内容,那播放的时候就会出错,但并非完全不能播放.
所以,关键是,检查读写的时候是否少了一两个字节.你可以用十六进制编辑器仔细核对读入和写出的内容差别在哪儿,再去检查程序的问题.


[其他解释]
你直接比对源文件和读出文件的二进制内容,看问题出在哪里。

[其他解释]

同意楼上,读出的二进制数据不要转成字符串。直接通过 Byte 数组写入新的二进制文件中。
[其他解释]
问题在于你将二进制文件转换成了文本,当你再次读出的时候,就不是原来的二进制数据了
[其他解释]

引用:
设计错误:

1) StrConv() 能对纯文本内容在 ANSI 和 Unicode 之间转换,不能用于非文本内容(音频、图像等)。
要么直接打包二进制内容、要么用 Base-64 编码进行转换。

2)你不能保证所用的“结束标志”不出现在文件内容当中,解包时会导致不正确的分割。
采用前缀长度的方案,解包时不需搜索可以直接按长度分割。

你说得对,我查了一下,转出来的字符串的长度比原来数组的元素总数少了好几千。不过我现在比较烦,数组很难在各个对象上传递。大家来看看这个帖子http://bbs.csdn.net/topics/390292907
[其他解释]
http://bbs.csdn.net/topics/390292907

热点排行