Tôi muốn viết một hàm đơn giản lặp qua các dòng của một tệp văn bản. Tôi tin vào 2.8
người ta có thể làm:Lặp lại các dòng của một tập tin
def lines(filename: String) : Iterator[String] = {
scala.io.Source.fromFile(filename).getLines
}
và đó là thế, nhưng trong 2.9
ở trên không hoạt động và thay vào đó tôi phải làm:
def lines(filename: String) : Iterator[String] = {
scala.io.Source.fromFile(new File(filename)).getLines()
}
Bây giờ, những rắc rối là, tôi muốn để tạo nên vòng lặp trên trong một sự hiểu biết for
:
for (l1 <- lines("file1.txt"); l2 <- lines("file2.txt")){
do_stuff(l1, l2)
}
này một lần nữa, được sử dụng để làm việc tốt với 2.8
nhưng gây ra một "quá ma ny mở tệp " ngoại lệ để được ném vào số 2.9
. Điều này là dễ hiểu - lần thứ hai lines
trong lần đọc kết thúc mở (và không đóng) một tệp cho mỗi dòng trong trường hợp đầu tiên.
Trong trường hợp của tôi, tôi biết rằng "file1.txt"
là lớn và tôi không muốn để hút nó vào
bộ nhớ, nhưng các tập tin thứ hai là nhỏ, vì vậy tôi có thể viết một khác nhau linesEager
như vậy:
def linesEager(filename: String): Iterator[String] =
val buf = scala.io.Source.fromFile(new File(filename))
val zs = buf.getLines().toList.toIterator
buf.close()
zs
và sau đó lần lượt của tôi cho-hiểu thành:
for (l1 <- lines("file1.txt"); l2 <- linesEager("file2.txt")){
do_stuff(l1, l2)
}
này hoạt động, nhưng rõ ràng là xấu xí. Ai đó có thể đề xuất một cách thống nhất & sạch cách để đạt được điều này. Có vẻ như bạn cần một cách cho trình lặp số được trả lại bởi lines
đến close
tệp khi đến cuối và điều này phải xảy ra trong 2.8
đó là lý do tại sao nó hoạt động ở đó?
Cảm ơn!
BTW - đây là một phiên bản tối thiểu của chương trình đầy đủ cho thấy vấn đề này:
import java.io.PrintWriter
import java.io.File
object Fail {
def lines(filename: String) : Iterator[String] = {
val f = new File(filename)
scala.io.Source.fromFile(f).getLines()
}
def main(args: Array[String]) = {
val smallFile = args(0)
val bigFile = args(1)
println("helloworld")
for (w1 <- lines(bigFile)
; w2 <- lines(smallFile)
)
{
if (w2 == w1){
val msg = "%s=%s\n".format(w1, w2)
println("found" + msg)
}
}
println("goodbye")
}
}
On 2.9.0
tôi biên dịch với scalac WordsFail.scala
và sau đó tôi có được điều này:
[email protected]:$ scalac WordsFail.scala
[email protected]:$ 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)
Mã hoạt động cho tôi trong REPL (Scala 2.9). –
Nó không phải là ';' không may. –
@userunknown Nó hoạt động nhưng nó không mở rộng. (Hãy tưởng tượng các tệp lớn/nhiều dòng.) – Debilski