scala中用于嵌套资源的托管(ARM)
所以,我在scala中有这段代码,我正在将其转换为托管代码scala中用于嵌套资源的托管(ARM),scala,scala-arm,Scala,Scala Arm,所以,我在scala中有这段代码,我正在将其转换为托管代码 val file_out = new FileOutputStream(new java.io.File(filePath, resultFile + ".tar.gz")); val buffer_out = new BufferedOutputStream(file_out); val gzip_out = new GzipCompressorOutputStream(buffer_out); val tar_out = new T
val file_out = new FileOutputStream(new java.io.File(filePath, resultFile + ".tar.gz"));
val buffer_out = new BufferedOutputStream(file_out);
val gzip_out = new GzipCompressorOutputStream(buffer_out);
val tar_out = new TarArchiveOutputStream(gzip_out);
try {
addFileToTarGz(tar_out, filePath + "/" + resultFolder, "");
} finally {
tar_out.finish();
tar_out.close();
gzip_out.close();
buffer_out.close();
file_out.close();
}
第一次尝试是:
val file = new java.io.File(filePath, s"$resultFile.tar.gz")
managed(new FileOutputStream(file))
.acquireAndGet(stream => managed(new BufferedOutputStream(stream))
.acquireAndGet(buffer => managed(new GzipCompressorOutputStream(buffer))
.acquireAndGet(gzip => managed(new TarArchiveOutputStream(gzip))
.acquireAndGet(tar => {
try {
addFileToTarGz(tar, filePath + "/" + resultFolder, "")
} finally {
tar.finish()
}
}))))
但是,它看起来不太可读。有没有更好的方法使它既可管理又可读?您考虑过加载模式吗
def withResource[T](block: Resource => T): T = {
val resource = new Resource
try {
block(resource)
} finally {
resource.close()
}
}
然后你会像这样使用它:
withResourse { resource =>
// do something with resource
}
如果对这些文件中的每一个使用单独的加载,那么最终将得到嵌套块。。。(在某些情况下,这可能是最合理的选择),但在这里,我想这样做就足够了:
def withTarStream(filePath: String, resultFile: String)(block: TarArchiveOutputStream => T): T = {
val fileOut = new FileOutputStream(new java.io.File(filePath, resultFile))
val bufferOut = new BufferedOutputStream(fileOut)
val gzipOut = new GzipCompressorOutputStream(bufferOut)
val tarOut = new TarArchiveOutputStream(gzipOut)
try {
block(tarOut)
} finally {
tarOut.finish()
tarOut.close()
gzipOut.close()
bufferOut.close()
fileOut.close()
}
}
用法如下:
withTarStream(filePath, s"$resultFile.tar.gz") { tarStream =>
addFileToTarGz(tarStream, filePath + "/" + resultFolder, "")
}
根据@Mateusz Kubuszok的建议,我尝试了以下变化:
private def withResource[T: Resource : Manifest, X](t: T, block: T => X): X = managed(t).acquireAndGet(x => block(x))
withResource(new FileOutputStream(file),
(x:FileOutputStream) => withResource(new BufferedOutputStream(x),
(y: BufferedOutputStream) => withResource(new GzipCompressorOutputStream(y),
(z: GzipCompressorOutputStream) => withResource(new TarArchiveOutputStream(z),
(tar: TarArchiveOutputStream) => writeTar(tar, filePath, resultFolder)))));
然后还将上述内容重构为以下形式:
private def withResource[T: Resource : Manifest, X](t: T, block: T => X): X = managed(t).acquireAndGet(x => block(x))
def writeInFile(x: FileOutputStream): Try[Unit] = withResource(new BufferedOutputStream(x), writeInBuffer)
def writeInBuffer(y: BufferedOutputStream): Try[Unit] = withResource(new GzipCompressorOutputStream(y), writeGzipStream)
def writeGzipStream(z: GzipCompressorOutputStream): Try[Unit] = withResource(new TarArchiveOutputStream(z), writeTarStream)
val file = new File(filePath, s"$resultFile.tar.gz")
withResource(new FileOutputStream(file), writeInFile);
第二天,一位同事提到了这一点,这看起来比上面两个都好:我仍在探索如何将结果/错误传播出这个块
val file = new File(filePath, s"$resultFile.tar.gz")
for {
stream <- managed(new FileOutputStream(file))
buffer <- managed(new BufferedOutputStream(stream))
gzip <- managed(new GzipCompressorOutputStream(buffer))
tar <- managed(new TarArchiveOutputStream(gzip))
} {
writeTar(tar)
}
val file=新文件(文件路径,s“$resultFile.tar.gz”)
对于{
使用a更好地理解一元流ManagedResource
@cchantep你能对我下面的答案发表评论吗?这是你建议的吗?(对于{a compute(a,b)}
val tarOutputStream: ManagedResource[TarArchiveOutputStream] = (for {
stream <- managed(new FileOutputStream(file))
buffer <- managed(new BufferedOutputStream(stream))
gzip <- managed(new GzipCompressorOutputStream(buffer))
tar <- managed(new TarArchiveOutputStream(gzip))
} yield tar)
Try (tarOutputStream.acquireAndGet(writeTarStream(_))) match {
case Failure(e) => Failure(e)
case Success(_) => Success(new File(s"$filePath/$runLabel.tar.gz"))
}