Scala 在文件的行上迭代
我想写一个简单的函数,它遍历文本文件的行。我相信Scala 在文件的行上迭代,scala,io,iterator,Scala,Io,Iterator,我想写一个简单的函数,它遍历文本文件的行。我相信2.8可以做到: def lines(filename: String) : Iterator[String] = { scala.io.Source.fromFile(filename).getLines } 就是这样,但是在2.9中,上面的内容不起作用,我必须这样做: def lines(filename: String) : Iterator[String] = { scala.io.Source.fromFile(ne
2.8
可以做到:
def lines(filename: String) : Iterator[String] = {
scala.io.Source.fromFile(filename).getLines
}
就是这样,但是在2.9
中,上面的内容不起作用,我必须这样做:
def lines(filename: String) : Iterator[String] = {
scala.io.Source.fromFile(new File(filename)).getLines()
}
现在,问题是,我想在中组合上述迭代器,以便理解:
for ( l1 <- lines("file1.txt"); l2 <- lines("file2.txt") ){
do_stuff(l1, l2)
}
然后将我的理解转化为:
for (l1 <- lines("file1.txt"); l2 <- linesEager("file2.txt")){
do_stuff(l1, l2)
}
在2.9.0
上,我使用scalac-WordsFail.scala进行编译,然后得到以下结果:
rjhala@goto:$ scalac WordsFail.scala
rjhala@goto:$ scala Fail passwd words
helloworld
java.io.FileNotFoundException: passwd (Too many open files)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:120)
at scala.io.Source$.fromFile(Source.scala:91)
at scala.io.Source$.fromFile(Source.scala:76)
at Fail$.lines(WordsFail.scala:8)
at Fail$$anonfun$main$1.apply(WordsFail.scala:18)
at Fail$$anonfun$main$1.apply(WordsFail.scala:17)
at scala.collection.Iterator$class.foreach(Iterator.scala:652)
at scala.io.BufferedSource$BufferedLineIterator.foreach(BufferedSource.scala:30)
at Fail$.main(WordsFail.scala:17)
at Fail.main(WordsFail.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at scala.tools.nsc.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:78)
at scala.tools.nsc.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:24)
at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:88)
at scala.tools.nsc.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:78)
at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:101)
at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:33)
at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:40)
at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:56)
at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:80)
at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:89)
at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
rjhala@goto:$scalac WordsFail.scala
rjhala@goto:$scala失败密码字
地狱世界
java.io.FileNotFoundException:passwd(打开的文件太多)
在java.io.FileInputStream.open(本机方法)
位于java.io.FileInputStream。(FileInputStream.java:120)
位于scala.io.Source$.fromFile(Source.scala:91)
位于scala.io.Source$.fromFile(Source.scala:76)
失败时$行(WordsFail.scala:8)
失败时$$anonfun$main$1.apply(WordsFail.scala:18)
失败时$$anonfun$main$1.apply(WordsFail.scala:17)
位于scala.collection.Iterator$class.foreach(Iterator.scala:652)
位于scala.io.BufferedSource$BufferedLineIterator.foreach(BufferedSource.scala:30)
失败时$.main(WordsFail.scala:17)
at Fail.main(WordsFail.scala)
在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处
位于sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)中
位于java.lang.reflect.Method.invoke(Method.java:597)
在scala.tools.nsc.util.ScalaClassLoader$$anonfun$run$1.apply处(ScalaClassLoader.scala:78)
位于scala.tools.nsc.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:24)
位于scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:88)
位于scala.tools.nsc.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:78)
位于scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:101)
位于scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:33)
位于scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:40)
位于scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:56)
在scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:80)中
位于scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:89)
位于scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
也许你应该看看scala手臂(https://github.com/jsuereth/scala-arm)并让文件(文件输入流)在后台自动关闭。提供了一种很好的机制,可以在使用完资源后自动关闭资源
import resource._
import scala.io.Source
for (file1 <- managed(Source.fromFile("file1.txt"));
l1 <- file1.getLines();
file2 <- managed(Source.fromFile("file2.txt"));
l2 <- file2.getLines()) {
do_stuff(l1, l2)
}
导入资源_
导入scala.io.Source
对于(file1 Code one在REPL(Scala 2.9)中为我工作)。不幸的是,它不是;
。@userunknown它可以工作,但不能扩展。(想象大文件/许多行。)你错了,2.8
也没有关闭任何东西,这可以很容易地通过在示例程序上运行lsof
来验证(或者通过查看源代码更费劲)。如果你对2.9
有问题,而你对2.8
没有问题,那么这些问题一定来自其他地方。将其转换为列表不会导致整个文件保存在内存中吗?我希望避免这种情况……但是file2.txt
很小,因此应该可以接受。另外,这就是你的lineseger
所做的(.toList
),除了你在内存中创建它,然后在file1.txt
中的每一行都扔掉它。嗨,戴夫,是的,你是对的。我误解了理解中的不同动作必须有相同的类型,所以当toList
时,无关的toliterator
就足够了……谢谢!@RanjitJhala-只有当您从表单中生成一个值以供理解时,类型才需要兼容。不一定相同,但兼容。
rjhala@goto:$ scalac WordsFail.scala
rjhala@goto:$ scala Fail passwd words
helloworld
java.io.FileNotFoundException: passwd (Too many open files)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:120)
at scala.io.Source$.fromFile(Source.scala:91)
at scala.io.Source$.fromFile(Source.scala:76)
at Fail$.lines(WordsFail.scala:8)
at Fail$$anonfun$main$1.apply(WordsFail.scala:18)
at Fail$$anonfun$main$1.apply(WordsFail.scala:17)
at scala.collection.Iterator$class.foreach(Iterator.scala:652)
at scala.io.BufferedSource$BufferedLineIterator.foreach(BufferedSource.scala:30)
at Fail$.main(WordsFail.scala:17)
at Fail.main(WordsFail.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at scala.tools.nsc.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:78)
at scala.tools.nsc.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:24)
at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:88)
at scala.tools.nsc.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:78)
at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:101)
at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:33)
at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:40)
at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:56)
at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:80)
at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:89)
at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
import resource._
import scala.io.Source
for (file1 <- managed(Source.fromFile("file1.txt"));
l1 <- file1.getLines();
file2 <- managed(Source.fromFile("file2.txt"));
l2 <- file2.getLines()) {
do_stuff(l1, l2)
}