Scala中BufferedSource的mkString读取文件追加换行符是否为预期行为?
为什么Scala读取单行文件时mkString带换行,getLines().mkString却不带?
嘿,这个问题其实是Scala的io.Source两个API的设计逻辑差异导致的,咱们一步步拆解来看:
首先先还原你的操作场景:
➜ ~ vi some_random_file_mkstring ➜ ~ wc -l < some_random_file_mkstring 1
这里要注意一个细节:大多数Unix/Linux下的文本编辑器在保存单行内容时,会自动在末尾追加一个换行符(这是系统中文本文件的惯例,换行符是行的结束标志),所以你的文件实际内容是"somerandomstring\n",而不是单纯的"somerandomstring"。
接下来看两种读取方式的区别:
- 直接调用
mkStringio.Source.fromFile返回的是一个字符迭代器,它会读取文件里的所有原始字符,包括末尾的换行符。mkString的作用就是把迭代器里的所有字符直接拼接起来,自然就包含了那个隐藏的换行符:
scala> io.Source.fromFile("some_random_file_mkstring").mkString res0: String = "somerandomstring\n" scala> io.Source.fromFile("some_random_file_mkstring").mkString.contains("\n") res1: Boolean = true
- 调用
getLines().mkStringgetLines()方法的设计初衷就是按行解析内容,并且自动剥离每行末尾的换行符——不管是中间行的换行,还是文件最后一行的换行。它会把整个文件按换行符分割成一个字符串迭代器,每个元素都是去掉换行的行内容,之后mkString拼接这些元素,自然就不会有换行符残留了。
举个更直观的例子:如果文件内容是"hello\nworld\n",getLines()会返回Iterator("hello", "world"),拼接后就是"helloworld",完全没有多余的换行。
如果你的需求是获取文件的纯文本内容(去掉换行符),用getLines().mkString是更稳妥的选择;如果需要保留文件里的所有原始字符(包括换行、空格等),再使用直接的mkString。
内容的提问来源于stack exchange,提问作者curious
相关产品推荐
相关产品推荐

