Android向SQL Server数据库存储文件的编码适配难题
问题根源与解决方案
你的问题核心出在Android端读取二进制文件的方式错误,而非编码或Base64的适配问题。先理清楚关键差异:
原来的ASP.NET代码直接获取文件的原始字节数组:
file.ARCHIVE = FileUpload1.FileBytes
这一步拿到的是文件的原始二进制数据,没有经过任何字符编码转换,直接存入SQL Server的Image字段,所以Web系统能正常读取。
但你现在的Android代码用InputStreamReader+BufferedReader读取文件,这是用来处理文本文件的方式!二进制文件(比如图片、PDF、压缩包等)包含很多无法被字符编码(UTF-8/ASCII)正确解析的字节,用字符流读取时会破坏原始数据(比如把非法字符替换成占位符),导致最终得到的字符串和原始文件字节完全不一致,后续即使转Base64也没用——因为源头的字节已经错了。
正确实现步骤
1. Android端:正确读取二进制文件并转Base64
直接读取文件的字节数组,再转成Base64字符串(HTTP传输二进制数据时,Base64是安全的文本编码方式):
// 读取文件为字节数组 public static byte[] readFileToBytes(Context context, String filename) throws IOException { InputStream inputStream = context.openFileInput(filename); ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream(); int bufferSize = 1024; byte[] buffer = new byte[bufferSize]; int len; while ((len = inputStream.read(buffer)) != -1) { byteBuffer.write(buffer, 0, len); } inputStream.close(); return byteBuffer.toByteArray(); } // 转成Base64字符串发送 byte[] fileBytes = readFileToBytes(context, filename); String base64Str = Base64.encodeToString(fileBytes, Base64.DEFAULT); // 把base64Str发送到WebService
2. ASP.NET WebService端:解码Base64并存入数据库
接收Base64字符串后,解码回字节数组,再用和原系统一致的方式存入SQL Server:
// 假设WebService接收的参数是base64FileStr byte[] fileBytes = Convert.FromBase64String(base64FileStr); // 用EF存入数据库(和原系统逻辑一致) using (var context = new YourDbContext()) { var file = new YourFileEntity(); file.ARCHIVE = fileBytes; // 其他字段赋值... context.SaveChanges(); } // 如果用SqlCommand的方式: command.Parameters.Add("@ARCHIVE", SqlDbType.Image).Value = fileBytes;
为什么原来的Android代码会出错?
InputStreamReader会将输入流的字节按**默认字符编码(通常是UTF-8)**转换成字符,但二进制文件的字节序列不一定符合UTF-8编码规则:
- 比如某些字节组合不是合法的UTF-8字符,会被替换成
�(替换字符),导致原始字节丢失。 - 读取时用
readLine()还会忽略换行符相关的字节,进一步破坏数据结构。
这种方式只适合读取文本文件(比如.txt、.json),绝对不能用来处理二进制文件。
内容的提问来源于stack exchange,提问作者Anderson Duarte de Amorim
相关产品推荐
相关产品推荐

