ImageVerifierCode 换一换
格式:DOCX , 页数:32 ,大小:49.24KB ,
资源ID:5829301      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bingdoc.com/d-5829301.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(java io系列14之 DataInputStream数据输入流的认知源码和示例Word文档格式.docx)为本站会员(b****2)主动上传,冰点文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰点文库(发送邮件至service@bingdoc.com或直接QQ联系客服),我们立即给予删除!

java io系列14之 DataInputStream数据输入流的认知源码和示例Word文档格式.docx

1、”DataInputStream 中比较难以理解的函数就只有 readUTF(DataInput in);下面,对这个函数进行详细的介绍,其它的函数请参考源码中的注释。readUTF(DataInput in)源码如下: 1 public final static String readUTF(DataInput in) throws IOException 2 / 从“数据输入流”中读取“无符号的short类型”的值: 3 / 注意:UTF-8输入流的前2个字节是数据的长度 4 int utflen = in.readUnsignedShort(); 5 byte bytearr = nul

2、l; 6 char chararr = null; 7 8 / 如果in本身是“数据输入流”, 9 / 则,设置字节数组bytearr = 数据输入流的成员bytearr 10 / 设置字符数组chararr = 的成员chararr 11 / 否则的话,新建数组bytearr和chararr 12 if (in instanceof DataInputStream) 13 DataInputStream dis = (DataInputStream)in; 14 if (dis.bytearr.length utflen) 15 dis.bytearr = new byteutflen*2;

3、 16 dis.chararr = new charutflen*2; 17 18 chararr = dis.chararr; 19 bytearr = dis.bytearr; 20 else 21 bytearr = new byteutflen; 22 chararr = new charutflen; 23 24 25 int c, char2, char3; 26 int count = 0; 27 int chararr_count=0; 28 29 / 从“数据输入流”中读取数据并存储到字节数组bytearr中;从bytearr的位置0开始存储,存储长度为utflen。 30

4、/ 注意,这里是存储到字节数组!而且读取的是全部的数据。 31 in.readFully(bytearr, 0, utflen); 32 33 / 将“字节数组bytearr”中的数据 拷贝到 “字符数组chararr”中 34 / 注意:这里相当于“预处理的输入流中单字节的符号”,因为UTF-8是1-4个字节可变的。 35 while (count 127) break; 40 count+; 41 / 将c保存到“字符数组chararr”中 42 chararrchararr_count+=(char)c; 43 44 45 / 处理完输入流中单字节的符号之后,接下来我们继续处理。 46

5、while (count 4) 54 / 若 UTF-8 是单字节,即 bytearrcount 对应是 “0xxxxxxx” 形式; 55 / 则 bytearrcount 对应的int类型的c的取值范围是 0-7。 56 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: 57 /* 0xxxxxxx*/ 58 count+; 59 chararrchararr_count+=(char)c; 60 break; 61 62 / 若 UTF-8 是双字节,即 bytearrcount 对应是 “110xxxxx 1

6、0xxxxxx” 形式中的第一个,即“110xxxxx” 63 / 则 bytearrcount 对应的int类型的c的取值范围是 12-13。 64 case 12: case 13: 65 /* 110x xxxx 10xx xxxx*/ 66 count += 2; 67 if (count utflen) 68 throw new UTFDataFormatException( 69 malformed input: partial character at end); 70 char2 = (int) bytearrcount-1; 71 if (char2 & 0xC0) != 0

7、x80) 72 throw new UTFDataFormatException( 73 malformed input around byte + count); 74 chararrchararr_count+=(char)(c & 0x1F) 84 throw new UTFDataFormatException( 85 86 char2 = (int) bytearrcount-2; 87 char3 = (int) bytearrcount-1; 88 if (char2 &= 0x80) | (char3 &= 0x80) 89 throw new UTFDataFormatExc

8、eption( 90 + (count-1); 91 chararrchararr_count+=(char)(c & 0x0F) 12) | 92 (char2 & 0x3F) 93 (char3 & 0); 94 break; 95 96 / 若 UTF-8 是四字节,即 bytearrcount 对应是 “11110xxx 10xxxxxx 10xxxxxx 10xxxxxx” 形式中的第一个,即“11110xxx” 97 / 则 bytearrcount 对应的int类型的c的取值是15 98 default: 99 /* 10xx xxxx, 1111 xxxx */100 thro

9、w new UTFDataFormatException(101 102 103 104 / The number of chars produced may be less than utflen105 return new String(chararr, 0, chararr_count);106 (01) readUTF()的作用,是从输入流中读取UTF-8编码的数据,并以String字符串的形式返回。(02) 知道了readUTF()的作用之后,下面开始介绍readUTF()的流程:第1步,读取出输入流中的UTF-8数据的长度。代码如下:int utflen = in.readUnsi

10、gnedShort();UTF-8数据的长度包含在它的前两个字节当中;我们通过readUnsignedShort()读取出前两个字节对应的正整数就是UTF-8数据的长度。第2步,创建2个数组:字节数组bytearr 和 字符数组chararr。 1 if (in instanceof DataInputStream) 2 DataInputStream dis = (DataInputStream)in; 3 if (dis.bytearr.length 4 dis.bytearr = new byteutflen*2; 5 dis.chararr = new charutflen*2; 6

11、7 chararr = dis.chararr; 8 bytearr = dis.bytearr; 9 else 10 bytearr = new byteutflen;11 chararr = new charutflen;12 首先,判断该输入流本身是不是DataInputStream,即数据输入流;若是的话,则,设置字节数组bytearr = 设置字符数组chararr = 否则的话,新建数组bytearr和chararr。第3步,将UTF-8数据全部读取到“字节数组bytearr”中。in.readFully(bytearr, 0, utflen);注意:这里是存储到字节数组,而不是字

12、符数组!第4步,对UTF-8中的单字节数据进行预处理。1 while (count 6 count+;7 / 将c保存到“字符数组chararr”中8 chararrchararr_count+=(char)c;9 UTF-8的数据是变长的,可以是1-4个字节;在readUTF()中,我们最终是将全部的UTF-8数据保存到“字符数组(而不是字节数组)”中,再将其转换为String字符串。由于UTF-8的单字节和ASCII相同,所以这里就将它们进行预处理,直接保存到“字符数组chararr”中。对于其它的UTF-8数据,则在后面进行处理。第5步,对“第4步 预处理”之后的数据,接着进行处理。/

13、处理完输入流中单字节的符号之后,接下来我们继续处理。while (count / 若 UTF-8 是单字节,即 bytearrcount 对应是 “0xxxxxxx” 形式; / 则 bytearrcount 对应的int类型的c的取值范围是 0-7。 case 0: /* 0xxxxxxx*/ count+; chararrchararr_count+=(char)c; break; / 若 UTF-8 是双字节,即 bytearrcount 对应是 “110xxxxx 10xxxxxx” 形式中的第一个,即“110xxxxx” / 则 bytearrcount 对应的int类型的c的取值范

14、围是 12-13。 case 12: /* 110x xxxx 10xx xxxx*/ count += 2; if (count throw new UTFDataFormatException( char2 = (int) bytearrcount-1; if (char2 & chararrchararr_count+=(char)(c & (char2 & / 若 UTF-8 是三字节,即 bytearrcount 对应是 “1110xxxx 10xxxxxx 10xxxxxx” 形式中的第一个,即“1110xxxx” / 则 bytearrcount 对应的int类型的c的取值是14

15、 。 case 14: /* 1110 xxxx 10xx xxxx 10xx xxxx */ count += 3; char2 = (int) bytearrcount-2; char3 = (int) bytearrcount-1; if (char2 & (char2 & (char3 & / 若 UTF-8 是四字节,即 bytearrcount 对应是 “11110xxx 10xxxxxx 10xxxxxx 10xxxxxx” 形式中的第一个,即“11110xxx” / 则 bytearrcount 对应的int类型的c的取值是15 default: /* 10xx xxxx, 1

16、111 xxxx */ (a) 我们将下面的两条语句一起进行说明c = (int) bytearrcount &switch (c 4) . 首先,我们必须要理解 为什么要这么做(执行上面2条语句)呢?原因很简单,这么做的目的就是为了区分UTF-8数据是几位的;因为UTF-8的数据是14字节不等。我们先看看UTF-8在14位情况下的格式。-+-1字节 UTF-8的通用格式 | 0xxxxxxx2字节 UTF-8的通用格式 | 110xxxxx 10xxxxxx3字节 UTF-8的通用格式 | 1110xxxx 10xxxxxx 10xxxxxx4字节 UTF-8的通用格式 | 11110xxx

17、 10xxxxxx 10xxxxxx 10xxxxxx执行 c = (int) bytearrcount & 和 c4 这2项操作之后,上面的数据变成1字节 UTF-8的变换后对应的int类型值 | 00000000 00000000 00000000 00000xxx (范围是07) 2字节 UTF-8的变换后对应的int类型值 | 00000000 00000000 00000000 0000110x (范围是1213) 3字节 UTF-8的变换后对应的int类型值 | 00000000 00000000 00000000 00001110 (范围是14) 4字节 UTF-8的变换后对应的

18、int类型值 | 00000000 00000000 00000000 00001111 (范围是15) 为什么会是这样呢?我们以“2字节 UTF-8的通用格式”来说明。它的通用格式是 “110xxxxx 10xxxxxx”,我们在操作时,只会操作第1个字节,即只会操作“110xxxxx”(a.1) 在执行 c = (int) bytearrcount & 时,首先将 bytearrcount 转换成int。“110xxxxx”转成int类型之后,变成“11111111 11111111 11111111 110xxxxx”因为“110xxxxx”是负数(第1为是1),所以转换成int类型时多

19、出来的位补1。(a.2) 接着 c = (int) bytearrcount & 中,会将 “转换成int类型后的bytearrcount” 与 “0xff”进行 逻辑与(即&) 操作。结果如下:“00000000 00000000 00000000 110xxxxx”(a.3) 执行 c4 时,会将上面的结果左移4位。得到的结果如下:“00000000 00000000 00000000 0000110x”(b) 上面的理解之后,swicth (c4) . 其中的省略号部分就相当容易理解了。我们还是以“2字节 UTF-8的通用格式”来说明。它会执行 case 12 和 case 13;源码如下:count += 2;if (count char2 = (int) bytearrcount-1;if (char2 &chararrchararr_count+=(char)(c & 6) | (char2 &(b.1) 由于这种情况对应的UTF-8数据是“2字节”的,因此,执行count+2;直接跳

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2