向高手请教解压缩反序列化的问题

问题描述

下面的fun()函数对data进行解压缩并反序列化voidfun(){byte[]data=getData();byte[]data2=myDecompress(data);//调用myDecompress函数解压缩BinaryFormatterbf=newBinaryFormatter();MemoryStreamms=newMemoryStream(data2);objectsurrogate=bf.Deserialize(ms);//反序列化}(1)privatebyte[]myDecompress(byte[]data)//解压缩函数一,这段代码没问题{MemoryStreamms=newMemoryStream(data);GZipStreamzipStream=newGZipStream(ms,CompressionMode.Decompress,true);byte[]buffer=newbyte[4096];MemoryStreamoutput=newMemoryStream();intread=-1;read=zipStream.Read(buffer,0,buffer.Length);while(read>0){output.Write(buffer,0,read);read=zipStream.Read(buffer,0,buffer.Length);}zipStream.Close();ms.Close();returnoutput.ToArray();}(2)privatebyte[]myDecompress2(byte[]data)//解压缩函数二,这段代码被调用后会产生异常{MemoryStreamms=newMemoryStream();GZipStreamzipStream=newGZipStream(ms,CompressionMode.Decompress,true);byte[]buffer=newbyte[data.Length];//如果数组data的长度太长,是不是这句写的不合理呢?zipStream.Read(buffer,0,data.Length);returnbuffer;}本人觉得第2段代码直接返回buffer跟第一段的代码效果一样,但这样当调用fun()函数中的objectsurrogate=bf.Deserialize(ms);时会引发SerializationException异常:EndofStreamencounteredbeforeparsingwascompleted.然后在函数myDecompress2中byte[]buffer=newbyte[data.Length];//如果数组data的长度太长,是不是这句写的不合理呢?请教各位,谢谢!

解决方案

解决方案二:
(2)privatebyte[]myDecompress2(byte[]data)//解压缩函数二,这段代码被调用后会产生异常{MemoryStreamms=newMemoryStream();GZipStreamzipStream=newGZipStream(ms,CompressionMode.Decompress,true);byte[]buffer=newbyte[data.Length];//如果数组data的长度太长,是不是这句写的不合理呢?zipStream.Read(buffer,0,data.Length);returnbuffer;}问题太大了把MemoryStreamms=newMemoryStream();//空~~byte[]buffer=newbyte[data.Length];解压后的大小不是这个你返回了一个空~~然后去反序列化空~~
解决方案三:
2)privatebyte[]myDecompress2(byte[]data)//解压缩函数二,这段代码被调用后会产生异常{MemoryStreamms=newMemoryStream();GZipStreamzipStream=newGZipStream(ms,CompressionMode.Decompress,true);byte[]buffer=newbyte[data.Length];//如果数组data的长度太长,是不是这句写的不合理呢?zipStream.Read(buffer,0,data.Length);returnbuffer.ToArray();}

解决方案四:
privatebyte[]myDecompress2(byte[]data)//解压缩函数二,这段代码被调用后会产生异常{MemoryStreamms=newMemoryStream();GZipStreamzipStream=newGZipStream(ms,CompressionMode.Decompress,true);byte[]buffer=newbyte[data.Length];//如果数组data的长度太长,是不是这句写的不合理呢?zipStream.Read(buffer,0,data.Length);returnbuffer.ToArray();}
解决方案五:
不要意思把函数myDecompress2(byte[]data)里第一句更正如下:MemoryStreamms=newMemoryStream(data);
解决方案六:
回3楼没有buffer.ToArray()这个方法
解决方案七:
引用5楼yangxinglouis的回复:

回3楼没有buffer.ToArray()这个方法

byte[]buffer是一个数组,怎么会没有.ToArray()方法?你测试过了?
解决方案八:
对呀测试过了没有这个方法
解决方案九:
问题应该是处在buffer数组的长度上buffer数组的长度定义应该是取解压缩后的字符流长度byte[]buffer=newbyte[data.Length];==>byte[]buffer=newbyte[zipStream.Length];
解决方案十:
读取的方法同样也要修改,希望能对你有所帮助
解决方案十一:
回楼上我把方法改称这样子:privatebyte[]myDecompress2(byte[]data)//解压缩函数二,这段代码被调用后会产生异常{MemoryStreamms=newMemoryStream();GZipStreamzipStream=newGZipStream(ms,CompressionMode.Decompress,true);byte[]buffer=newbyte[zipStream.Length];zipStream.Read(buffer,0,Convert.ToInt32(zipStream.Length));returnbuffer;}执行到此句byte[]buffer=newbyte[zipStream.Length];时抛出NotSupportedExceptionThisoperationisnotsupported.
解决方案十二:
对于方法二抛出的异常更详细的信息如下:<ExceptionType>System.Runtime.Serialization.SerializationException,mscorlib,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089</ExceptionType><Message>Binarystream'0'doesnotcontainavalidBinaryHeader.Possiblecausesareinvalidstreamorobjectversionchangebetweenserializationanddeserialization.</Message>
解决方案十三:
下面给出测试代码(windows应用程序)希望通过大家的努力能知道为什么!usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.Text;usingSystem.Windows.Forms;usingSystem.Data.SqlClient;usingSystem.IO;usingSystem.IO.Compression;usingSystem.Runtime.Serialization.Formatters.Binary;namespaceDataSetApp11{publicpartialclassForm1:Form{publicForm1(){InitializeComponent();}privatevoidbutton1_Click(objectsender,EventArgse){stringconnStr=@"server=WT-SH-GWZ172XSQLEXPRESS;database=test;trusted_connection=true";stringsql="select*frommyUser";DataSetds=newDataSet();using(SqlConnectionconn=newSqlConnection(connStr)){using(SqlDataAdapterda=newSqlDataAdapter(sql,conn)){da.Fill(ds);byte[]data=serializeAndCompressDataSet(ds);//byte[]buffer=myDecompress2(data);//会产生异常byte[]buffer=myDecompress(data);//没问题BinaryFormatterbf=newBinaryFormatter();MemoryStreamms=newMemoryStream(buffer);DataSetds2=bf.Deserialize(ms)asDataSet;ms.Close();this.dataGridView1.DataSource=ds2.Tables[0];}}}privatebyte[]myDecompress2(byte[]data)//解压缩函数二,这段代码被调用后会产生异常{MemoryStreamms=newMemoryStream();GZipStreamzipStream=newGZipStream(ms,CompressionMode.Decompress,true);byte[]buffer=newbyte[data.Length];//如果数组data的长度太长,是不是这句写的不合理呢?zipStream.Read(buffer,0,Convert.ToInt32(data.Length));returnbuffer;}privatebyte[]myDecompress(byte[]data)//解压缩函数一,这段代码没问题{MemoryStreamms=newMemoryStream(data);GZipStreamzipStream=newGZipStream(ms,CompressionMode.Decompress,true);byte[]buffer=newbyte[4096];MemoryStreamoutput=newMemoryStream();intread=-1;read=zipStream.Read(buffer,0,buffer.Length);while(read>0){output.Write(buffer,0,read);read=zipStream.Read(buffer,0,buffer.Length);}zipStream.Close();ms.Close();returnoutput.ToArray();}privatebyte[]serializeAndCompressDataSet(DataSetds)//序列化并压缩DataSet{MemoryStreamms=newMemoryStream();BinaryFormatterbf=newBinaryFormatter();bf.Serialize(ms,ds);byte[]data=ms.ToArray();ms.Close();MemoryStreamoutput=newMemoryStream();GZipStreamzipStream=newGZipStream(output,CompressionMode.Compress,true);zipStream.Write(data,0,data.Length);zipStream.Close();output.Close();returnoutput.ToArray();}}}
解决方案十四:
zipStream.Length==》zipStream.BaseStream.Length原因就是buffer数组的长度定义应该是取解压缩后的字符流长度
解决方案十五:
另外MemoryStreamms=newMemoryStream();=>MemoryStreamms=newMemoryStream(data);这个上面有人已经说了
解决方案:
另外如果压缩的字符流比较长zipStream.Read(buffer,0,Convert.ToInt32(zipStream.BaseStream.Length));直接转换成int并不合适,这里只是一个例子,你需要拆分为多个byte数组处理
解决方案:
privatebyte[]myDecompress2(byte[]data){MemoryStreamms=newMemoryStream(data);GZipStreamzipStream=newGZipStream(ms,CompressionMode.Decompress,true);byte[]buffer=newbyte[zipStream.BaseStream.Length];zipStream.Read(buffer,0,Convert.ToInt32(zipStream.BaseStream.Length));returnbuffer;}请问楼上如果用这种方法是不是读一次就有了呢?但上面的代码还是会有异常。我检查了发现byte[]buffer=myDecompress(data);跟byte[]buffer=myDecompress2(data);buffer的维数是不同的,myDecompress2的小
解决方案:
zipStream.Read(buffer,0,Convert.ToInt32(zipStream.BaseStream.Length));要读多次的因为Read方法的参数是Int,而byte数组的Length是long。可以把byte数组拆成N个长度为2048的数组,最后Contact就好
解决方案:
给你贴下完整的例子源代码吧usingSystem;usingSystem.IO;usingSystem.IO.Compression;publicclassGZipTest{privateconstintbuffer_size=100;publicstaticintReadAllBytesFromStream(Streamstream,byte[]buffer){//Usethismethodisusedtoreadallbytesfromastream.intoffset=0;inttotalCount=0;while(true){intbytesRead=stream.Read(buffer,offset,buffer_size);if(bytesRead==0){break;}offset+=bytesRead;totalCount+=bytesRead;}returntotalCount;}publicstaticboolCompareData(byte[]buf1,intlen1,byte[]buf2,intlen2){//Usethismethodtocomparedatafromtwodifferentbuffers.if(len1!=len2){Console.WriteLine("Numberofbytesintwobufferaredifferent{0}:{1}",len1,len2);returnfalse;}for(inti=0;i<len1;i++){if(buf1[i]!=buf2[i]){Console.WriteLine("byte{0}isdifferent{1}|{2}",i,buf1[i],buf2[i]);returnfalse;}}Console.WriteLine("Allbytescompare.");returntrue;}publicstaticvoidGZipCompressDecompress(stringfilename){Console.WriteLine("Testcompressionanddecompressiononfile{0}",filename);FileStreaminfile;try{//OpenthefileasaFileStreamobject.infile=newFileStream(filename,FileMode.Open,FileAccess.Read,FileShare.Read);byte[]buffer=newbyte[infile.Length];//Readthefiletoensureitisreadable.intcount=infile.Read(buffer,0,buffer.Length);if(count!=buffer.Length){infile.Close();Console.WriteLine("TestFailed:Unabletoreaddatafromfile");return;}infile.Close();MemoryStreamms=newMemoryStream();//Usethenewlycreatedmemorystreamforthecompresseddata.GZipStreamcompressedzipStream=newGZipStream(ms,CompressionMode.Compress,true);Console.WriteLine("Compression");compressedzipStream.Write(buffer,0,buffer.Length);//Closethestream.compressedzipStream.Close();Console.WriteLine("Originalsize:{0},Compressedsize:{1}",buffer.Length,ms.Length);//Resetthememorystreampositiontobegindecompression.ms.Position=0;GZipStreamzipStream=newGZipStream(ms,CompressionMode.Decompress);Console.WriteLine("Decompression");byte[]decompressedBuffer=newbyte[buffer.Length+buffer_size];//UsetheReadAllBytesFromStreamtoreadthestream.inttotalCount=GZipTest.ReadAllBytesFromStream(zipStream,decompressedBuffer);Console.WriteLine("Decompressed{0}bytes",totalCount);if(!GZipTest.CompareData(buffer,buffer.Length,decompressedBuffer,totalCount)){Console.WriteLine("Error.Thetwobuffersdidnotcompare.");}zipStream.Close();}//endtrycatch(InvalidDataException){Console.WriteLine("Error:Thefilebeingreadcontainsinvaliddata.");}catch(FileNotFoundException){Console.WriteLine("Error:Thefilespecifiedwasnotfound.");}catch(ArgumentException){Console.WriteLine("Error:pathisazero-lengthstring,containsonlywhitespace,orcontainsoneormoreinvalidcharacters");}catch(PathTooLongException){Console.WriteLine("Error:Thespecifiedpath,filename,orbothexceedthesystem-definedmaximumlength.Forexample,onWindows-basedplatforms,pathsmustbelessthan248characters,andfilenamesmustbelessthan260characters.");}catch(DirectoryNotFoundException){Console.WriteLine("Error:Thespecifiedpathisinvalid,suchasbeingonanunmappeddrive.");}catch(IOException){Console.WriteLine("Error:AnI/Oerroroccurredwhileopeningthefile.");}catch(UnauthorizedAccessException){Console.WriteLine("Error:pathspecifiedafilethatisread-only,thepathisadirectory,orcallerdoesnothavetherequiredpermissions.");}catch(IndexOutOfRangeException){Console.WriteLine("Error:YoumustprovideparametersforMyGZIP.");}}publicstaticvoidMain(string[]args){stringusageText="Usage:MYGZIP<inputfilename>";//Ifnofilenameisspecified,writeusagetext.if(args.Length==0){Console.WriteLine(usageText);}else{if(File.Exists(args[0]))GZipCompressDecompress(args[0]);}}}
解决方案:
1,压缩前长度和压缩后长度要分清2,Write和Read要分清

时间: 2024-07-30 06:19:11

向高手请教解压缩反序列化的问题的相关文章

高手请教,网卡堵塞

问题描述 我的系统经过差不多24小时运行以后(大概每天的高峰开始后1-2个小时),如果上午重起,那么第二天9点左右,如果下午重起机器,那么第二天3点左右网络堵塞,重起网卡不行,关掉WEBLOGIC后,网络又通了,可是重起WEBLOGIC后几分钟又被堵塞了,平常访问量比较大,双修日少点,所以双修日不会堵死,请教高手解答,急....

一个零基础自学编程的菜鸟真诚向各位高手请教!

问题描述 我是一个零基础,不是计算机专业的计算机编程爱好者,我非常喜欢编程做软件的那种感觉.但是我已经这里那里的公司混了一年了,依然感觉自己做不出来什么东西,目前最基本的SQLSERVER都不会用,但是目前又在一家公司硬着头皮学习,但是我知道我肯定留不长的.因为我的基础非常有限,因为家里穷,必须工作,否则连填饱肚子的钱都没有.我非常想突破自己现在的瓶颈,我不知道如何去突破.基本的C#语言看的懂,但是到运用他们完全不看书开发一项简单的任务时就不知所措,完全不知从哪里下手.书,我也买了不少,基本开了

向各位高手请教医疗信息化和企业ERP的问题!!!!!!

问题描述 最近想换一份工作,目前有两个方向,一个是医疗软件(his)实施工程师,另一个是ERP实施工程师,我想请教一下选择哪个方向发展前景比较好,请有经验的帮忙分析一下,谢谢 解决方案 解决方案二:怎么也没有个帮忙分析的

向各位高手请教下这个问题!

问题描述 form1中有一个button和listbox,其中的选项是书名,选择一个书名再按button,出现form2,有3个文本框,可以分别输入书的ID.作者.类别,在确认输入后将书名及其ID.作者.类别都存储至对应的struct中方便以后调用,以上过程该如何实现呢?如何存进对应的struct中?还请高手不吝赐教~谢谢! 解决方案 解决方案二:咋没人理呢?来个人教教偶····解决方案三:定义一个book类,属性ID,作者,类别,form1中有一个button和listbox选择一个书名再按b

新人请高手请教~怎样才能学好.Net

问题描述 .Net似乎没有java复杂,我很想把.Net学好,编程方面也算有基础,我在某培训中心学习,但是不知道该怎么下手,请教各位指点~谢谢 解决方案 解决方案二:java复杂吗?没看出来复杂是相对的,会的人就是不复杂不会的就是复杂:不过还是欢迎学习.net;自己想出自己想做什么就可以下手了:就是自己虚拟一个项目先学习学习.解决方案三:向你推荐两本书,我个人看过的,写的很好!Visualc#2005大学教程(中文版:电子工业出版社)很基础,且实例丰富,通俗易懂.c#高级编程(第四版)(中文版:

C# dataset 内存溢出,高手请教!

问题描述 表有200多个字段,400万记录.我知道数据量太大.但是没办法,我只能去处理这个表,而且必须为断开式,有高手能帮助解决一下吗? 解决方案 解决方案二:现在是什么问题?查询不出来还是怎么样了?是不是Fill的时候超时了?个人觉得还是从优化SQL去入手,将一些查询条件处理好一点,比如哪一个字段可以将整个数据的范围缩小,那么就把这个字段放在最前面.解决方案三:难道你必须一次将400W数据全部取出来吗?解决方案四:如果你必须一次将4M条记录读入内存,那我唯一能想到的就是让你换一台拥有更大内存的

log4j 高手请教 多账户多日志输出

问题描述 有个交易系统,账户定义文件不定多个,格式相同,账号密码等内容不同有个class是处理交易的,每个实例处理一个账户的交易问题:如何让这个class根据账户的不同,把日志输出到账户专用的日志文件中去?因为账户定义文件允许新增删除,所以希望log4j的配置也是动态的,尽量不要写死请把class中的相关设定代码和log4j配置文件的相关设置分别说明一下,多谢了 解决方案 解决方案二:ding..........................解决方案三:我也顶起吧..坐等楼下的答案了...解决

高手请教:一个关于方法重写的问题

问题描述 我们再重写一个父类的方法时,VS自动生成的方法存根总会默认一些代码,譬如我现在要写一个控件,重写Control类的Render方法,VS默认会生成的代码如下:protectedoverridevoidRender(HtmlTextWriterwriter){base.Render(writer);}我想问一下这里的base.Render(writer);是不是必须要加的啊,我不加也可以啊.在什么情况下必须要加上,如果加上的话,自己重写的代码应该放在这句的前面还是后面???谢谢 解决方案

全部家产拿出来向诸位高手请教一个Membership中的profile 以及 权限控制的问题!

问题描述 1,就是当我的网站里面有好几个角色的时候,比如.老师和学生:那么老师的属性肯定和学生的属性不一样,那么这个时候我再添加信息的时候如何来区分不同的用户添加不同的profile呢?然后同样的是读取,修改信息的问题!2,就是我用Membership控制权限的时候,如果我现在有一个功能目录的xml文件,这个功能目录自然是对应的我项目里面的文件夹目录,那么我如何通过Membership来控制这个功能目录的xml文件,当我哪种角色的用户进来的时候,就显示该角色所有用的功能目录.3,就是Member