字符流不能用于读写图片等二进制文件,因其强制进行字符编码/解码,而图片字节无法合法映射为unicode字符,导致数据失真;字节流才可原样搬运每个byte,确保二进制数据安全。

因为字符流在读写过程中会强制进行字符编码与解码,而图片这类二进制文件本身没有“字符含义”,强行按文本逻辑处理会导致数据失真。
核心问题:字符流本质是“语义化转换器”
Reader 和 Writer 不是简单搬运字节,而是把原始字节按指定编码(如 UTF-8、GBK)**解码成 char**,再把 char **重新编码成字节**写出去。这个过程依赖“该字节序列能合法映射为有效字符”。但图片文件的字节组合绝大多数无法对应任何可表示的 Unicode 字符——比如连续多个 0xFF 0xD8 0xFF(JPEG 文件头)在 UTF-8 下可能构成非法码点或被替换/丢弃,导致写入目标文件的数据与源文件不一致。
实际表现:看似成功,实则损坏
- 程序不会报错,复制操作“完成”,目标文件大小可能看起来正常;
- 但打开时显示“无法识别格式”“已损坏”或完全黑屏;
- 用十六进制编辑器对比会发现:关键字节(如文件头、像素块)已被篡改或截断。
根本区别:设计目标不同
字符流专为人类可读文本设计,它的价值在于:自动处理换行符统一(newLine())、按行读取(readLine())、规避中文乱码。这些能力对图片毫无意义,反而引入冗余转换和风险。
而字节流(如 FileInputStream/FileOutputStream)不做任何解释,原样搬运每个 byte,这才是二进制数据安全传输的唯一可靠方式。
一个常见误区澄清
有人尝试用 InputStreamReader 指定 ISO-8859-1 编码读取图片——虽然该编码是单字节且“几乎不丢失”,但 Writer 端仍需编码回字节,且 char 类型本身是 16 位,部分字节会被高位补零或截断,依然不可靠。这不是编码选得对不对的问题,而是整个字符流模型就不该用于二进制场景。











