- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试读取一个 zip 文件,检查它是否有一些必需的文件,然后将所有有效文件写入另一个 zip 文件。 basic introduction to java.util.zip有很多 Java 主义,我很想让我的代码更原生于 Scala。具体来说,我想避免使用 vars
.这是我所拥有的:
val fos = new FileOutputStream("new.zip");
val zipOut = new ZipOutputStream(new BufferedOutputStream(fos));
while (zipIn.available == 1) {
val entry = zipIn.getNextEntry
if (entryIsValid(entry)) {
zipOut.putNewEntry(new ZipEntry("subdir/" + entry.getName())
// read data into the data Array
var data = Array[Byte](1024)
var count = zipIn.read(data, 0, 1024)
while (count != -1) {
zipOut.write(data, 0, count)
count = zipIn.read(data, 0, 1024)
}
}
zipIn.close
}
zipOut.close
最佳答案
d我认为使用 Java 类并没有什么特别的错误,这些 Java 类被设计为按照它们设计的方式以命令式方式工作。惯用的 Scala 包括能够按预期使用惯用的 Java,即使样式确实有点冲突。
然而,如果你想——也许是作为一个练习,或者可能是因为它确实稍微澄清了逻辑——以一种更实用的无 var 的方式来做到这一点,你可以这样做。在 2.8 中,它特别好,所以即使你使用的是 2.7.7,我也会给出 2.8 的答案。
首先,我们需要设置问题,但您并没有完全解决这个问题,但假设我们有这样的事情:
import java.io._
import java.util.zip._
import scala.collection.immutable.Stream
val fos = new FileOutputStream("new.zip")
val zipOut = new ZipOutputStream(new BufferedOutputStream(fos))
val zipIn = new ZipInputStream(new FileInputStream("old.zip"))
def entryIsValid(ze: ZipEntry) = !ze.isDirectory
continually
collection.immutable.Stream
中的方法.它所做的是为您执行一个惰性求值循环。然后,您可以获取并过滤结果以终止和处理您想要的结果。当您想要成为迭代器时使用它是一种方便的模式,但事实并非如此。 (如果项目自行更新,您可以在
.iterate
或
Iterable
中使用
Iterator
——这通常会更好。)这是此案例的应用程序,使用了两次:一次用于获取条目,一次用于读/写数据 block :
val buffer = new Array[Byte](1024)
Stream.continually(zipIn.getNextEntry).
takeWhile(_ != null).filter(entryIsValid).
foreach(entry => {
zipOut.putNextEntry(new ZipEntry("subdir/"+entry.getName))
Stream.continually(zipIn.read(buffer)).takeWhile(_ != -1).
foreach(count => zipOut.write(buffer,0,count))
})
}
zipIn.close
zipOut.close
.
在一些行的末尾!我通常会把它写在一条长线上,但最好把它包起来,这样你就可以在这里看到所有内容。
continually
的用途之一。 .
Stream.continually(zipIn.read(buffer))
zipIn.read(buffer)
根据需要多次存储结果的整数。
.takeWhile(_ != -1)
-1
时会退出。 .
.foreach(count => zipOut.write(buffer,0,count))
zipIn
的事实。刚刚被调用以获取流的下一个元素——如果您尝试再次执行此操作,而不是单次通过流,它将失败,因为
buffer
将被覆盖。但是这里没关系。
Stream.continually
不可用,并且构建自定义的开销
Iterator
对于这种情况不值得。 (但是,如果我要进行更多的 zip 文件处理并且可以重用代码,那将是值得的。)
null
从
getNextEntry
返回.考虑到这一点,我编辑了之前的代码(有一个
takeWhile(_ => zipIn.available==1)
现在是
takeWhile(_ != null)
)并在下面提供了一个基于 2.7.7 迭代器的版本(注意主循环有多小,一旦你通过定义迭代器的工作,它们确实使用 vars):
val buffer = new Array[Byte](1024)
class ZipIter(zis: ZipInputStream) extends Iterator[ZipEntry] {
private var entry:ZipEntry = zis.getNextEntry
private var cached = true
private def cache { if (entry != null && !cached) {
cached = true; entry = zis.getNextEntry
}}
def hasNext = { cache; entry != null }
def next = {
if (!cached) cache
cached = false
entry
}
}
class DataIter(is: InputStream, ab: Array[Byte]) extends Iterator[(Int,Array[Byte])] {
private var count = 0
private var waiting = false
def hasNext = {
if (!waiting && count != -1) { count = is.read(ab); waiting=true }
count != -1
}
def next = { waiting=false; (count,ab) }
}
(new ZipIter(zipIn)).filter(entryIsValid).foreach(entry => {
zipOut.putNextEntry(new ZipEntry("subdir/"+entry.getName))
(new DataIter(zipIn,buffer)).foreach(cb => zipOut.write(cb._2,0,cb._1))
})
zipIn.close
zipOut.close
关于scala - 使用 ZipInputStreams 和 ZipOutpuStreams 时如何避免 Scala 中的可变变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2849303/
下面是代码片段。 while (iterator.hasNext()) { FileItemStream item = iterator.next(); InputStream in
我有 Java 代码,它传入一个 Zip 文件列表,其中一个文件的格式故意错误。该 Zip 文件位于列表末尾。 我的代码看起来有点像: System.out.println("Hi Stinky Pe
如果我使用包含一些带有变音符号的文件(例如 1-2GF-969##JÖN.pdf)的 zip 文件运行以下程序,我会得到 IllegalArgumentException。 我的应用程序必须支持所有语
下面是一些从仅包含一个文件的 zip 文件中提取文件的代码。但是,提取的文件与通过 WinZip 或其他压缩实用程序提取的同一文件不匹配。如果文件包含奇数个字节,我预计它可能会关闭一个字节(因为我的缓
我正在尝试从 ZIP 存档中读取 XML 文件。相关代码如下: ZipInputStream zis = new ZipInputStream(is); ZipEntry entry = zis.ge
我正在开发一个电子阅读器应用程序(使用 skyepub ),它基本上将加密的书籍下载到文件系统中(并将解密 key 保存在数据库中),当用户尝试阅读它时,它会加载将书存入内存并解密。 问题是有些书的第
我正在尝试从 ZIP 存档中读取 XML 文件。相关代码如下: ZipInputStream zis = new ZipInputStream(is); ZipEntry entry = zis.ge
有java.io.ZipInputStream膨胀和java.io.ZipOutputStream这会泄气。 但有时我不希望这样。有时,当使用接受 InputStream 的第三方 API 时,我想要
我想知道是否有一种方法可以直接从 ZipFile/ZipInputStream 读取特定文件,而不必遍历整个条目集。我想这可能是一个很大的开销,如果存档包含大量文件。有没有更好的办法? 我知道这可以用
因此,在 ZIP 文件的末尾,例如最后 64K,有一个中央目录,从中您可以看到 ZIP 文件本身包含的内容。 现在我已将 ZIP 文件加载到 ZipInputStream 中,在此之前我已声明一个 l
我有一个 JSF 应用程序(Majorra 2.1.20、PrimeFaces 4.0-SNAPSHOT、OmniFaces 1.4.1,在 Glassfish 3.1.2 上运行),可以在 Fire
那么使用ZipInputStream时,要在WEB上获取Zip文件的InputStream,使用时是否会将整个ZIP文件下载到用户计算机中? 例如,如果程序使用 ZipInputStream 来查看
在我们完全读取流之前,是否可以找到/估计 ZipInputStream 的大小? 例如,我们可以在读取用户数据之前使用 getNextEntry 获取条目的元数据。 Inputstream 有一个方法
我可以通过 ZipInputStream,但在开始迭代之前,我想获取迭代期间所需的特定文件。我该怎么做? ZipInputStream zin = new ZipInputStream(myInput
我正在使用 AsyncTask 解压缩文件,一切似乎都进行得很顺利(ZIP 存档中的所有文件都已提取),但我的解压缩方法从未完成。 这是我的解压类的源代码: public class MyUnzipp
假设我们有这样的代码: File file = new File("zip1.zip"); ZipInputStream zis = new ZipInputStream(new FileInputS
我们正在尝试修改 2007 MS Excel 中的 XML 文件之一。为此,将使用 Java 的 ZipInputStream 解压缩 xlsx 文件,然后使用 ZipOutputStream 将其复
我正在尝试从 zip 中解压缩特定文件。我首先得到一个ZipInputStream: ZipInputStream zipIn = new ZipInputStream(new BufferedInp
我做了this问题,我看到存在一个名为 ZipInputStream 的构造函数: ZipInputStream(BufferedInputStream, 字符集) 但是调试器向我抛出错误: ZipI
private byte[] loadClassData(String className) { ZipInputStream in = null; FileInputStream f
我是一名优秀的程序员,十分优秀!