C#学习教程:将非常大的二进制文件逐步转换为Base64String文件太大,无法立即加载到内存中(它们会抛出OutOfMemoryExceptions),否则这将是一项简单的任务。我不想单独处理ZIP文件的内容,我想处理整个ZIP文件。问题:我可以将整个ZIP文件(目前测试大小从1MB到800MB)转换为Base64String,但是当我将其转换回来时,它已损坏。新的ZIP文件大小正确,它被Windows和WinRAR/7-Zip等识别为ZIP文件,我什至可以查看ZIP文件内部并查看具有正确尺寸/属性的内容,但是当我尝试从ZIP文件中提取,我得到:“错误:0x80004005”,这是一般错误代码。我不确定腐败发生在何处或为何发生。我做了一些研究,注意到以下几点:如果你有一个大文本文件,你可以逐渐将它转换为Base64String而不会出现问题。如果在整个文件上调用Convert.ToBase64String,它将产生:“abcdefghijklmnopqrstuvwx”,然后在文件的两个部分上调用将产生:“abcdefghijkl”和“mnopqrstuvwx”。不幸的是,如果文件是二进制的,结果就不同了。虽然整个文件可能会生成:“abcdefghijklmnopqrstuvwx”,但尝试将其分成两部分会生成类似于:“oiweh87yakgb”和“kyckshfguywp”的内容。有没有办法在避免这种损坏的同时增量地对二进制文件进行base64编码?我的代码:privatevoidConvertLargeFile(){FileStreaminputStream=newFileStream("C:\Users\test\Desktop\my.zip",FileMode.Open,FileAccess.Read);byte[]buffer=newbyte[MultipleOfThree];intbytesRead=inputStream.Read(buffer,0,buffer.Length);while(bytesRead>0){byte[]secondaryBuffer=newbyte[buffer.Length];intsecondaryBufferBytesRead=bytesRead;Array.Copy(buffer,secondaryBuffer,buffer.Length);boolisFinalChunk=false;Array.Clear(buffer,0,buffer.Length);bytesRead=inputStream.Read(buffer,0,buffer.Length);如果(bytesRead==0){isFinalChunk=true;buffer=newbyte[secondaryBufferBytesRead];Array.Copy(secondaryBuffer,buffer,buffer.length);}Stringbase64String=Convert.ToBase64String(isFinalChunk?buffer:secondaryBuffer);File.AppendAllText("C:\Users\test\Desktop\Base64Zip",base64String);}inputStream.Dispose();解码更相同。我使用上面base64String变量的大小(根据我测试的原始缓冲区大小而变化)作为解码缓冲区大小。然后我调用Convert.FromBase64String()并写入另一个文件名/路径而不是Convert.ToBase64String()。编辑:在我急于减少代码时(我将它重构为一个新项目,与其他处理分开,以消除不是问题的核心代码)我引入了一个错误。当缓冲区应该被使用时,base64转换应该在所有迭代的secondaryBuffer上执行,保存最后一个(由isFinalChunk标识)。我已经更正了上面的代码。编辑#2:感谢大家的意见/反馈。更正错误后(见上面的编辑),我重新测试了我的代码,它现在可以正常工作了。我打算测试和实施@rene的解决方案,因为它看起来是最好的,但我认为我应该让每个人都知道我发现了什么。基于WiktorZychla博客中显示的代码,以下代码有效。与IvanStoev在Convert.ToBase64String的备注部分中指出的相同解决方案//使用System.Security.CryptographyprivatevoidConvertLargeFile(){//encodevarfilein=@"C:UserstestDesktopmy.zip";varfileout=@"C:UserstestDesktopBase64Zip";使用(FileStreamfs=File.Open(fileout,FileMode.Create))使用(varcs=newCryptoStream(fs,newToBase64Transform(),CryptoStreamMode.Write))使用(varfi=File.Open(filein,FileMode.Open))){fi.CopyTo(cs);}//zip文件现在存储在base64zip中//并使用(FileStreamf64=File.Open(fileout,FileMode.Open))使用(varcs=newCryptoStream(f64,newFromBase64Transform(),CryptoStreamMode.Read)进行解码)使用(varfo=File.Open(filein+".orig",FileMode.Create)){cs.CopyTo(fo);}//原始文件在my.zip.orig//使用commandlinetool//fcmy.zipmy.zip.orig//验证起始文件和编码解码文件//是否相同}the该代码使用System.Security.Cryptography命名空间中的标准类,并使用CryptoStream和FromBase64Transform及其相应的ToBase64Transform您可以通过将偏移量和长度传递给Convert.ToBase64String来避免使用辅助缓冲区,如下所示:zip",FileMode.Open,FileAccess.Read)){byte[]buffer=newbyte[MultipleOfThree];intbytesRead=inputStream.Read(buffer,0,buffer.Length);while(bytesRead>0){Stringbase64String=Convert.ToBase64String(buffer,0,bytesRead);File.AppendAllText("C:\Users\test\Desktop\Base64Zip",base64String);bytesRead=inputStream.Read(buffer,0,buffer.Length);}}}以上应该可行,但我认为Rene的回答实际上是一个更好的解决方案使用这段代码:以上是C#学习教程:将一个非常大的二进制文件逐步转换为Base64String的全部内容分享。如果对大家有用,需要进一步了解C#学习教程,希望大家多加关注——FileAccess.Read)){intbuffer_size=30000;//或3byte[]buffer=newbyte[buffer_size]的任何倍数;intbytesRead=inputStream.Read(buffer,0,buffer.Length);while(bytesRead>0){byte[]buffer2=buffer;if(bytes阅读本文整理自网络,不代表立场,如涉及侵权,请点击右侧联系管理员删除。如需转载,请注明出处:
