如何在 Scala 中写入文件?
对于阅读来说,有一个有用的抽象Source
。如何将行写入文本文件?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
对于阅读来说,有一个有用的抽象Source
。如何将行写入文本文件?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(19)
这是标准 Scala 中缺少的功能之一,我发现它非常有用,因此我将其添加到我的个人库中。 (您可能也应该有一个个人库。)代码如下所示:
并且使用方式如下:
This is one of the features missing from standard Scala that I have found so useful that I add it to my personal library. (You probably should have a personal library, too.) The code goes like so:
and it's used like this:
编辑 2019 年(8 年后),Scala-IO 不是很活跃(如果有的话),< a href="https://stackoverflow.com/users/871202/li-haoyi">李浩毅推荐了他自己的库
lihaoyi/os-lib
,他在下面介绍。2019 年 6 月,Xavier Guihot 在
使用
,一个用于执行自动资源管理的实用程序。编辑(2011 年 9 月):自从 Eduardo Costa 询问 Scala2.9 以来,自从 Rick-777 评论 scalax.IO 提交历史 自 2009 年中期以来几乎不存在...
Scala-IO 已更改位置:请参阅其 GitHub 存储库,来自 Jesse Eichar (也就这样):
原始答案(2011年1月),与scala-io的旧地方:
如果你不想等待Scala2.9,你可以使用 scala-incubator / scala-io 库。
(如“为什么Scala Source不关闭底层InputStream? ”)
请参阅样品
Edit 2019 (8 years later), Scala-IO being not very active, if any, Li Haoyi suggests his own library
lihaoyi/os-lib
, that he presents below.June 2019, Xavier Guihot mentions in his answer the library
Using
, a utility for performing automatic resource management.Edit (September 2011): since Eduardo Costa asks about Scala2.9, and since Rick-777 comments that scalax.IO commit history is pretty much non-existent since mid-2009...
Scala-IO has changed place: see its GitHub repo, from Jesse Eichar (also on SO):
Original answer (January 2011), with the old place for scala-io:
If you don't want to wait for Scala2.9, you can use the scala-incubator / scala-io library.
(as mentioned in "Why doesn't Scala Source close the underlying InputStream?")
See the samples
与 Rex Kerr 的答案类似,但更通用。首先我使用辅助函数:
然后我将其用作:
等等
。
Similar to the answer by Rex Kerr, but more generic. First I use a helper function:
Then I use this as:
and
etc.
一个简单的答案:
A simple answer:
给出另一个答案,因为我对其他答案的编辑被拒绝。
这是最简洁和简单的答案(类似于 Garret Hall 的)
这类似于 Jus12,但没有冗长且正确的 代码风格
请注意,
try finally
不需要大括号,也不需要 lambda,并注意占位符语法的使用。还要注意更好的命名。Giving another answer, because my edits of other answers where rejected.
This is the most concise and simple answer (similar to Garret Hall's)
This is similar to Jus12, but without the verbosity and with correct code style
Note you do NOT need the curly braces for
try finally
, nor lambdas, and note usage of placeholder syntax. Also note better naming.不幸的是,对于最重要的答案,Scala-IO 已经死了。如果您不介意使用第三方依赖项,请考虑使用我的 OS-Lib 库。这使得处理文件、路径和文件系统变得非常容易:
它具有用于写入文件<的单行代码< /a>, 附加到文件, 覆盖文件,以及许多其他有用/常见的操作
Unfortunately for the top answer, Scala-IO is dead. If you don't mind using a third-party dependency, consider using my OS-Lib library. This makes working with files, paths and the filesystem very easy:
It has one-liners for writing to files, appending to files, overwriting files, and many other useful/common operations
下面是使用 Scala 编译器库的简洁单行:
或者,如果您想使用 Java 库,您可以执行以下 hack:
Here is a concise one-liner using the Scala compiler library:
Alternatively, if you want to use the Java libraries you can do this hack:
一个用于使用
java.nio
保存/读取String
的衬垫。这不适合大文件,但可以完成工作。
一些链接:
java.nio.file.Files.write
java .lang.String.getBytes
scala.collection.JavaConverters
scala.collection.immutable.List.mkString
One liners for saving/reading to/from
String
, usingjava.nio
.This isn't suitable for large files, but will do the job.
Some links:
java.nio.file.Files.write
java.lang.String.getBytes
scala.collection.JavaConverters
scala.collection.immutable.List.mkString
从 Scala 2.13 开始,标准库提供了专用的资源管理实用程序:
使用
。在这种情况下,它可以与诸如
PrintWriter
或BufferedWriter
扩展 < code>AutoCloseable 以便写入文件,并且无论如何,之后关闭资源:例如,使用
java.io
API:或者使用
java.nio
API:Starting
Scala 2.13
, the standard library provides a dedicated resource management utility:Using
.It can be used in this case with resources such as
PrintWriter
orBufferedWriter
which extendsAutoCloseable
in order to write to a file and, no matter what, close the resource afterwards:For instance, with
java.io
api:Or with
java.nio
api:我编写的微型库: https://github.com/pathikrit/better-files
或
A micro library I wrote: https://github.com/pathikrit/better-files
or
2019 年 9 月 1 日更新:
finally
会吞下try
抛出的原始Exception
如果finally
抛出的错误code> code throws anException
在查看了所有关于如何在 Scala 中轻松编写文件的答案(其中一些非常好)之后,我遇到了三个问题
close
方法顺序 - 注意:以相反顺序关闭依赖资源特别是在发生故障的情况下是java.lang.AutoCloseable
规范倾向于导致非常有害且难以发现的错误和运行时故障在开始之前,我的目标不是简洁。它是为了让 Scala/FP 初学者(通常是来自 Java 的初学者)更容易理解。最后,我会将所有内容整合在一起,然后增加简洁性。
首先,需要更新
using
方法以使用Try
(同样,简洁性不是这里的目标)。它将被重命名为tryUsingAutoCloseable
:上面
tryUsingAutoCloseable
方法的开头可能会令人困惑,因为它似乎有两个参数列表,而不是通常的单个参数列表。这称为柯里化。我不会详细介绍柯里化的工作原理或它偶尔有用的地方。事实证明,对于这个特定的问题空间,它是完成这项工作的正确工具。接下来,我们需要创建方法
tryPrintToFile
,它将创建(或覆盖现有的)File
并写入List[String]
。它使用一个FileWriter
,它被一个BufferedWriter
封装,而BufferedWriter
又被一个PrintWriter
封装。为了提高性能,定义了比BufferedWriter
的默认值大得多的默认缓冲区大小defaultBufferSize
,并分配了值 65536。这是代码(再次强调,简洁性是不是这里的目标):
上面的
tryPrintToFile
方法很有用,因为它采用List[String]
作为输入并将其发送到File
。现在让我们创建一个tryWriteToFile
方法,该方法接受String
并将其写入File
。下面是代码(我会让你猜测这里简洁性的优先级):
最后,能够以
String
的形式获取File
的内容是很有用的。虽然 scala.io.Source 提供了一种方便的方法来轻松获取File
的内容,但必须在File
上使用close
方法>Source 用于释放底层 JVM 和文件系统句柄。如果不这样做,那么资源不会被释放,直到 JVM GC(垃圾收集器)开始释放Source
实例本身。即使这样,JVM 也只能保证 GC 会调用 Finalize 方法来关闭资源。这意味着显式调用close
方法是客户端的责任,就像客户端有责任在的实例上关闭
。为此,我们需要处理 scala.io.Source 的 using 方法的第二个定义。close
方法一样。 java.lang.AutoCloseable这是它的代码(仍然不够简洁):
这是一个在超级简单的行流文件读取器中使用它的示例(当前用于从数据库输出中读取制表符分隔的文件):
上述函数的更新版本已作为对不同但相关的 StackOverflow 问题。
现在,将所有内容与提取的导入结合在一起(使其更容易粘贴到 Eclipse ScalaIDE 和 IntelliJ Scala 插件中存在的 Scala 工作表中,以便轻松将输出转储到桌面,以便更轻松地使用文本编辑器进行检查),这就是代码的样子(更加简洁):
作为 Scala/FP 新手,我花费了很多时间(主要是令人头疼的挫败感)来获得上述知识和解决方案。我希望这可以帮助其他 Scala/FP 新手更快地克服这个特定的学习难题。
UPDATE on 2019/Sep/01:
finally
would swallow originalException
thrown bytry
iffinally
code threw anException
After reviewing all of these answers on how to easily write a file in Scala, and some of them are quite nice, I had three issues:
scala.util.Try
close
method is performed on each dependent resource in reverse order - Note: closing dependent resources in reverse order ESPECIALLY IN THE EVENT OF A FAILURE is a rarely understood requirement of thejava.lang.AutoCloseable
specification which tends to lead to very pernicious and difficult to find bugs and run time failuresBefore starting, my goal isn't conciseness. It's to facilitate easier understanding for Scala/FP beginners, typically those coming from Java. At the very end, I will pull all the bits together, and then increase the conciseness.
First, the
using
method needs to be updated to useTry
(again, conciseness is not the goal here). It will be renamed totryUsingAutoCloseable
:The beginning of the above
tryUsingAutoCloseable
method might be confusing because it appears to have two parameter lists instead of the customary single parameter list. This is called currying. And I won't go into detail how currying works or where it is occasionally useful. It turns out that for this particular problem space, it's the right tool for the job.Next, we need to create method,
tryPrintToFile
, which will create a (or overwrite an existing)File
and write aList[String]
. It uses aFileWriter
which is encapsulated by aBufferedWriter
which is in turn encapsulated by aPrintWriter
. And to elevate performance, a default buffer size much larger than the default forBufferedWriter
is defined,defaultBufferSize
, and assigned the value 65536.Here's the code (and again, conciseness is not the goal here):
The above
tryPrintToFile
method is useful in that it takes aList[String]
as input and sends it to aFile
. Let's now create atryWriteToFile
method which takes aString
and writes it to aFile
.Here's the code (and I'll let you guess conciseness's priority here):
Finally, it is useful to be able to fetch the contents of a
File
as aString
. Whilescala.io.Source
provides a convenient method for easily obtaining the contents of aFile
, theclose
method must be used on theSource
to release the underlying JVM and file system handles. If this isn't done, then the resource isn't released until the JVM GC (Garbage Collector) gets around to releasing theSource
instance itself. And even then, there is only a weak JVM guarantee thefinalize
method will be called by the GC toclose
the resource. This means that it is the client's responsibility to explicitly call theclose
method, just the same as it is the responsibility of a client to tallclose
on an instance ofjava.lang.AutoCloseable
. For this, we need a second definition of the using method which handlesscala.io.Source
.Here's the code for this (still not being concise):
And here is an example usage of it in a super simple line streaming file reader (currently using to read tab-delimited files from database output):
An updated version of the above function has been provided as an answer to a different but related StackOverflow question.
Now, bringing that all together with the imports extracted (making it much easier to paste into Scala Worksheet present in both Eclipse ScalaIDE and IntelliJ Scala plugin to make it easy to dump output to the desktop to be more easily examined with a text editor), this is what the code looks like (with increased conciseness):
As a Scala/FP newbie, I've burned many hours (in mostly head-scratching frustration) earning the above knowledge and solutions. I hope this helps other Scala/FP newbies get over this particular learning hump faster.
下面是使用 scalaz-stream 将一些行写入文件的示例。
Here's an example of writing some lines to a file using scalaz-stream.
为了超越 samthebest 和他之前的贡献者,我改进了命名和简洁性:
To surpass samthebest and the contributors before him, I have improved the naming and conciseness:
无依赖项,带有错误处理
Either
用于错误处理代码
用法
No dependencies, with error handling
Either
for error handlingCode
Usage
2019 更新:
总结 - Java NIO(或异步的 NIO.2)仍然是 Scala 支持的最全面的文件处理解决方案。以下代码创建一些文本并将其写入新文件:
Path
对象OutputStream
write
函数中2019 Update:
Summary - Java NIO (or NIO.2 for async) is still the most comprehensive file processing solution supported in Scala. The following code creates and writes some text to a new file:
Path
object with your chosen file nameOutputStream
write
function与这个答案类似,下面是一个
fs2
(版本1.0.4)的示例:Similar to this answer, here is an example with
fs2
(version 1.0.4):为我工作
Worked for me
此行有助于从数组或字符串写入文件。
This line helps to write a file from an Array or String.
如果您的项目中无论如何都有 Akka Streams,它会提供一条简短的信息:
Akka docs > 流式文件 IO< /a>
If you are anyways having Akka Streams in your project, it provides a one-liner:
Akka docs > Streaming File IO