统计CSV每行大小用line.getBytes().length还是line.length()*Character.BYTES
统计CSV单行字节大小的方案选择
要和Mac文件管理器显示的CSV文件常规大小对齐,使用line.getBytes().length(需显式指定文件对应字符集)的方案更准确。
两种计算方式的本质区别
line.length() * Character.BYTES
Java中Character.BYTES固定为2,对应的是字符串以UTF-16编码存储的单字符字节长度。该计算方式得到的是字符串转为UTF-16编码后的总字节数,但日常使用的CSV文件几乎不会采用UTF-16编码存储,因此这个结果和实际文件存储大小偏差极大。你测试得到的1682是841的两倍,就是因为测试行的内容均为单字节字符(英文、数字、半角符号等),UTF-16编码下每个字符占2字节,正好是UTF-8编码下字节数的两倍。line.getBytes().length
该方法是将字符串按照指定字符集编码为字节数组后统计长度,和文件实际存储的编码逻辑一致,因此结果更贴合实际文件大小。
使用getBytes()的注意事项
- 显式指定字符集:无参的
getBytes()会默认使用JVM的系统字符集,可能和CSV文件的实际编码不一致导致统计偏差,建议根据文件编码显式指定,例如UTF-8编码的文件使用line.getBytes(StandardCharsets.UTF_8).length计算。 - 补全换行符字节:使用
BufferedReader.readLine()读取行内容时,会自动丢弃行尾的换行符(Mac/Unix下为\n占1字节,Windows下为\r\n占2字节),累加总大小时需要对应加上换行符的字节数,否则总大小会小于实际文件大小。
补充说明
如果你需要完全对齐Mac Finder显示的文件大小,要注意Finder默认展示的是文件占用的磁盘块大小(会比文件实际逻辑字节数略大,对齐磁盘块分配规则),如果你只是需要统计文件的逻辑字节总大小,或者需要用单行大小做后续业务逻辑,上述调整后的getBytes()方案即可满足需求。
内容的提问来源于stack exchange,提问作者stackerstack
相关产品推荐
相关产品推荐

