无法将位于索引 78 处的字节 [92] 由指定的代码页转换为 Unicode

iseelxj 2010-05-11 11:58:00
客户端通过TCPIP访问服务器端,取回被序列化的dataset,然后反序列化。
但是同样的操作,有时候出,有时候正常,很是郁闷。dataset中有汉字内容

服务端


public static byte[] DataSetSerializerCompression(DataSet ds)
{
string tmp = Path.Combine(
Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location),
string.Concat(Guid.NewGuid().ToString(),".dat"));
try
{
IFormatter formatter = new BinaryFormatter();//定义BinaryFormatter以序列化DataSet对象

MemoryStream ms = new MemoryStream();//创建内存流对象

formatter.Serialize(ms, ds);//把DataSet对象序列化到内存流

byte[] buffer = ms.ToArray();//把内存流对象写入字节数组

ms.Close();//关闭内存流对象

ms.Dispose();//释放资源

FileStream fs = File.Create(tmp);//创建文件

GZipStream gzipStream = new GZipStream(fs, CompressionMode.Compress, true);//创建压缩对象

gzipStream.Write(buffer, 0, buffer.Length);//把压缩后的数据写入文件

gzipStream.Close();//关闭压缩流,这里要注意:一定要关闭,要不然解压缩的时候会出现小于4K的文件读取不到数据,大于4K的文件读取不完整

gzipStream.Dispose();//释放对象

fs.Close();//关闭流

fs.Dispose();//释放对象

buffer = File.ReadAllBytes(tmp);// 读取应用软件所在目录下的文件
return buffer;

}
finally
{
if (File.Exists(tmp))
{
File.Delete(tmp);
}
}
}


客户端:


public static DataSet DataSetDeserializeDecompre(byte[] b)
{
string tmp = Path.Combine(
Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location),
string.Concat(Guid.NewGuid().ToString(), ".dat"));
try
{
FileStream fss = File.Create(tmp);//创建文件
fss.Close();
File.WriteAllBytes(tmp, b);

FileStream fs = File.OpenRead(tmp);//打开文件

fs.Position = 0;//设置文件流的位置

GZipStream gzipStream = new GZipStream(fs, CompressionMode.Decompress);//创建解压对象

byte[] buffer = new byte[10240];//定义数据缓冲

int offset = 0;//定义读取位置

MemoryStream ms = new MemoryStream();//定义内存流

while ((offset = gzipStream.Read(buffer, 0, buffer.Length)) != 0)
{
ms.Write(buffer, 0, offset);//解压后的数据写入内存流
}

BinaryFormatter sfFormatter = new BinaryFormatter();//定义BinaryFormatter以反序列化DataSet对象

ms.Position = 0;//设置内存流的位置

DataSet ds;

try
{
ms.Seek(0, SeekOrigin.Begin);
ds = (DataSet)sfFormatter.Deserialize(ms);//反序列化
}
catch
{
throw;
}
finally
{
ms.Close();//关闭内存流
ms.Dispose();//释放资源
fs.Close();//关闭文件流
fs.Dispose();//释放资源
gzipStream.Close();//关闭解压缩流
gzipStream.Dispose();//
}
//释放资源
return ds;
}
finally
{
if (File.Exists(tmp))
{
File.Delete(tmp);
}
}
}
...全文
2197 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
大光呢 2010-08-05
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 xiaxue0525 的回复:]
LZ,我这边报出的错误是“无法将位于索引 95(索引值很随即) 处的字节 [FF](每次都是FF,每次) 由指定的代码页转换为 Unicode。”
我是直接在内存里操作的MemoryStream。
[/Quote]
补充,我跟踪显示 索引出的值不是FF,是另外的值,也很随机的(反正不是255)。
大光呢 2010-08-05
  • 打赏
  • 举报
回复
LZ,我这边报出的错误是“无法将位于索引 95(索引值很随即) 处的字节 [FF](每次都是FF,每次) 由指定的代码页转换为 Unicode。”
我是直接在内存里操作的MemoryStream。
大光呢 2010-08-05
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 beijingbeerman 的回复:]
楼主思路有问题。
服务器端:
首先,xml序列化的不对,应该把xml保存为文件。
Dataset ds=new Dataset();
...
ds.WriteXml("xml路径.xml",XmlWriteMode.WriteSchema);


第二,传送过程中不要用这种写法
GZipStream gzipStream = new GZipStream(fs, C……
[/Quote]

确实够稳定的,都TMD定到硬盘上去了,能不稳吗
iseelxj 2010-05-14
  • 打赏
  • 举报
回复
问题根源找到了,在server端。每次发送一个dataset时,先发序列化后的byte数,然后再发送
数据,也就是会做两次socket.send,两次要是连续发送的话,就不稳定。象下面这样做就没问题了

socket.send(size);
thread.sleep(200);
socket.send(data);
st200316 2010-05-13
  • 打赏
  • 举报
回复
看看是不是编码的问题
iseelxj 2010-05-13
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 iseelxj 的回复:]

问题出在

try
{
ms.Seek(0, SeekOrigin.Begin);
ds = (DataSet)sfFormatter.Deserialize(ms);//反序列化
}
……
[/Quote]

就是运行到这段代码时,有时候会出标题的错误
  • 打赏
  • 举报
回复
贴的代码太多,看着麻烦。你的代码跟你的标题有什么关系呢?
糊巴 2010-05-13
  • 打赏
  • 举报
回复
看不懂,很遗憾····
iseelxj 2010-05-13
  • 打赏
  • 举报
回复
都是中文系统,但不一定是一样的版本
beijingbeerman 2010-05-13
  • 打赏
  • 举报
回复
楼主思路有问题。
服务器端:
首先,xml序列化的不对,应该把xml保存为文件。
Dataset ds=new Dataset();
...
ds.WriteXml("xml路径.xml",XmlWriteMode.WriteSchema);


第二,传送过程中不要用这种写法
GZipStream gzipStream = new GZipStream(fs, CompressionMode.Decompress);//创建解压对象
直接用winrar软件的壳命令来压缩xml。然后通过socket传送到客户端。

客户端:
1。收到文件用winrar命令解压缩。保存xml文件到硬盘。
2。 ds.ReadXml("xml保存路径.xml");


我这种方法肯定可以,稳定性很高。
xingyuebuyu 2010-05-13
  • 打赏
  • 举报
回复
先在同样版本的操作系统和FRAMEWORK下进行测试,看包含中文时是否还会发生异常?

http://msdn.microsoft.com/zh-cn/library/system.text.decoderfallbackexception(VS.95).aspx

http://msdn.microsoft.com/zh-cn/library/302sbf78(v=VS.80).aspx
使用BinaryRead 和BinaryWrite,并且指定编码时先尝试不要抛出异常看看

若要启用错误检测并使类实例更加安全,请使用带有 throwOnInvalidBytes 参数的 UTF8Encoding 构造函数,并将该参数设置为 true。使用错误检测时,检测到无效字符序列或字节序列的方法将引发 ArgumentException。如果不使用错误检测,则不引发异常,并且通常会忽略无效序列。
iseelxj 2010-05-13
  • 打赏
  • 举报
回复
和编码应该没有关系,我用
textreader和textwriter,指定编码也不行
iseelxj 2010-05-12
  • 打赏
  • 举报
回复
问题出在

try
{
ms.Seek(0, SeekOrigin.Begin);
ds = (DataSet)sfFormatter.Deserialize(ms);//反序列化
}
catch
{
throw;
}
xiaowang1026 2010-05-12
  • 打赏
  • 举报
回复
关注,帮你顶
iseelxj 2010-05-12
  • 打赏
  • 举报
回复
救急啊
sxldfang 2010-05-12
  • 打赏
  • 举报
回复
用比如: ms.Position=0 来试试,没试,不知对否
iseelxj 2010-05-12
  • 打赏
  • 举报
回复
谁能指点一下啊
zhangguofang1129 2010-05-12
  • 打赏
  • 举报
回复
关注,帮顶
xrongzhen 2010-05-12
  • 打赏
  • 举报
回复
该走了 先不看了
加载更多回复(1)

110,577

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧