java 如何将 ZipInputStream 转换为 InputStream?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7853972/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I convert ZipInputStream to InputStream?
提问by newbie
I have code, where ZipInputSream is converted to byte[], but I don't know how I can convert that to inputstream.
我有代码,其中 ZipInputSream 转换为 byte[],但我不知道如何将其转换为 inputstream。
private void convertStream(String encoding, ZipInputStream in) throws IOException,
UnsupportedEncodingException
{
final int BUFFER = 1;
@SuppressWarnings("unused")
int count = 0;
byte data[] = new byte[BUFFER];
while ((count = in.read(data, 0, BUFFER)) != -1)
{
// How can I convert data to InputStream here ?
}
}
采纳答案by newbie
Here is how I solved this problem. Now I can get single files from ZipInputStream to memory as InputStream.
这是我解决这个问题的方法。现在我可以将 ZipInputStream 中的单个文件作为 InputStream 获取到内存中。
private InputStream convertZipInputStreamToInputStream(ZipInputStream in, ZipEntry entry, String encoding) throws IOException
{
final int BUFFER = 2048;
int count = 0;
byte data[] = new byte[BUFFER];
ByteArrayOutputStream out = new ByteArrayOutputStream();
while ((count = in.read(data, 0, BUFFER)) != -1) {
out.write(data);
}
InputStream is = new ByteArrayInputStream(out.toByteArray());
return is;
}
回答by ExtremeCoder
ZipInputStream is a subclass of InputStream.
ZipInputStream 是 InputStream 的子类。
http://download.oracle.com/javase/6/docs/api/java/util/zip/ZipInputStream.html
http://download.oracle.com/javase/6/docs/api/java/util/zip/ZipInputStream.html
回答by vad
Please find below example of function that will extract all files from ZIP archive. This function will not work with files in subfolders:
请在下面找到将从 ZIP 存档中提取所有文件的函数示例。此功能不适用于子文件夹中的文件:
private static void testZip() {
ZipInputStream zipStream = null;
byte buff[] = new byte[16384];
int readBytes;
try {
FileInputStream fis = new FileInputStream("./test.zip");
zipStream = new ZipInputStream(fis);
ZipEntry ze;
while((ze = zipStream.getNextEntry()) != null) {
if(ze.isDirectory()) {
System.out.println("Folder : "+ze.getName());
continue;//no need to extract
}
System.out.println("Extracting file "+ze.getName());
//at this moment zipStream pointing to the beginning of current ZipEntry, e.g. archived file
//saving file
FileOutputStream outFile = new FileOutputStream(ze.getName());
while((readBytes = zipStream.read(buff)) != -1) {
outFile.write(buff, 0, readBytes);
}
outFile.close();
}
} catch (Exception e) {
System.err.println("Error processing zip file : "+e.getMessage());
} finally {
if(zipStream != null)
try {
zipStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
回答by EdwinR
The zip code is fairly easy but I had issues with returning ZipInputStream as Inputstream. For some reason, some of the files contained within the zip had characters being dropped. The below was my solution and so far its been working.
邮政编码相当简单,但我在将 ZipInputStream 作为 Inputstream 返回时遇到了问题。出于某种原因,包含在 zip 中的某些文件的字符被删除。下面是我的解决方案,到目前为止它一直在工作。
private Map<String, InputStream> getFilesFromZip(final DataHandler dhZ,
String operation) throws ServiceFault
{
Map<String, InputStream> fileEntries = new HashMap<String, InputStream>();
try
{
DataSource dsZ = dhZ.getDataSource();
ZipInputStream zipIsZ = new ZipInputStream(dhZ.getDataSource()
.getInputStream());
try
{
ZipEntry entry;
while ((entry = zipIsZ.getNextEntry()) != null)
{
if (!entry.isDirectory())
{
Path p = Paths.get(entry.toString());
fileEntries.put(p.getFileName().toString(),
convertZipInputStreamToInputStream(zipIsZ));
}
}
}
finally
{
zipIsZ.close();
}
}
catch (final Exception e)
{
faultLocal(LOGGER, e, operation);
}
return fileEntries;
}
private InputStream convertZipInputStreamToInputStream(
final ZipInputStream in) throws IOException
{
ByteArrayOutputStream out = new ByteArrayOutputStream();
IOUtils.copy(in, out);
InputStream is = new ByteArrayInputStream(out.toByteArray());
return is;
}
回答by gpeche
ZipInputStream
allows to read ZIP contents directly: iterate using getNextEntry()
until you find the entry you want to read and then just read from the ZipInputStream
.
ZipInputStream
允许直接读取 ZIP 内容:迭代使用,getNextEntry()
直到找到要读取的条目,然后从 .zip 文件中读取ZipInputStream
。
If you don't want to just read ZIP content, but you need to apply an additional transform to the stream before passing to the next step, you can use PipedInputStream
and PipedOutputStream
. The idea would be similar to this (written from memory, might not even compile):
如果您不想只读取 ZIP 内容,但需要在传递到下一步之前对流应用额外的转换,则可以使用PipedInputStream
和PipedOutputStream
。这个想法与此类似(从内存中编写,甚至可能无法编译):
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
public abstract class FilterThread extends Thread {
private InputStream unfiltered;
public void setUnfilteredStream(InputStream unfiltered) {
this.unfiltered = unfiltered;
}
private OutputStream threadOutput;
public void setThreadOutputStream(OutputStream threadOutput) {
this.threadOutput = threadOutput;
}
// read from unfiltered stream, filter and write to thread output stream
public abstract void run();
}
...
public InputStream getFilteredStream(InputStream unfiltered, FilterThread filter) {
PipedInputStream filteredInputStream = new PipedInputStream();
PipedOutputStream threadOutputStream = new PipedOutputStream(filteredInputStream);
filter.setUnfilteredStream(unfiltered);
filter.setThreadOuptut(threadOutputStream);
filter.start();
return filteredInputStream;
}
...
public void clientCode() {
...
ZipInputStream zis = ...;// get ZIP stream
FilterThread filter = ...; // assign your implementation of FilterThread that transforms your ZipInputStream
InputStream filteredZipInputStream = getFilteredStream(zis, filter);
...
}