如何使用InputStream从ZIP读取文件?

我必须使用SFTP从ZIP存档(只有一个文件,我知道它的名字)中获取文件内容。 我唯一拥有的是ZIP的InputStream 。 大多数示例显示如何使用此语句获取内容:

 ZipFile zipFile = new ZipFile("location"); 

但正如我所说,我的本地机器上没有ZIP文件,我不想下载它。 InputStream是否足以读取?

UPD:这是我的方式:

 import java.util.zip.ZipInputStream; import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; public class SFTP { public static void main(String[] args) { String SFTPHOST = "host"; int SFTPPORT = 3232; String SFTPUSER = "user"; String SFTPPASS = "mypass"; String SFTPWORKINGDIR = "/dir/work"; Session session = null; Channel channel = null; ChannelSftp channelSftp = null; try { JSch jsch = new JSch(); session = jsch.getSession(SFTPUSER, SFTPHOST, SFTPPORT); session.setPassword(SFTPPASS); java.util.Properties config = new java.util.Properties(); config.put("StrictHostKeyChecking", "no"); session.setConfig(config); session.connect(); channel = session.openChannel("sftp"); channel.connect(); channelSftp = (ChannelSftp) channel; channelSftp.cd(SFTPWORKINGDIR); ZipInputStream stream = new ZipInputStream(channelSftp.get("file.zip")); ZipEntry entry = zipStream.getNextEntry(); System.out.println(entry.getName); //Yes, I got its name, now I need to get content } catch (Exception ex) { ex.printStackTrace(); } finally { session.disconnect(); channelSftp.disconnect(); channel.disconnect(); } } } 

下面是一个关于如何提取ZIP文件的简单示例,您需要检查该文件是否是目录。 但这是最简单的。

您缺少的步骤是读取输入流并将内容写入写入输出流的缓冲区。

 // Expands the zip file passed as argument 1, into the // directory provided in argument 2 public static void main(String args[]) throws Exception { if(args.length != 2) { System.err.println("zipreader zipfile outputdir"); return; } // create a buffer to improve copy performance later. byte[] buffer = new byte[2048]; // open the zip file stream InputStream theFile = new FileInputStream(args[0]); ZipInputStream stream = new ZipInputStream(theFile); String outdir = args[1]; try { // now iterate through each item in the stream. The get next // entry call will return a ZipEntry for each file in the // stream ZipEntry entry; while((entry = stream.getNextEntry())!=null) { String s = String.format("Entry: %s len %d added %TD", entry.getName(), entry.getSize(), new Date(entry.getTime())); System.out.println(s); // Once we get the entry from the stream, the stream is // positioned read to read the raw data, and we keep // reading until read returns 0 or less. String outpath = outdir + "/" + entry.getName(); FileOutputStream output = null; try { output = new FileOutputStream(outpath); int len = 0; while ((len = stream.read(buffer)) > 0) { output.write(buffer, 0, len); } } finally { // we must always close the output file if(output!=null) output.close(); } } } finally { // we must always close the zip file. stream.close(); } } 

代码摘录来自以下网站:

http://www.thecoderscorner.com/team-blog/java-and-jvm/12-reading-a-zip-file-from-java-using-zipinputstream#.U4RAxYamixR

好吧,我做到了这个:

  zipStream = new ZipInputStream(channelSftp.get("Port_Increment_201405261400_2251.zip")); zipStream.getNextEntry(); sc = new Scanner(zipStream); while (sc.hasNextLine()) { System.out.println(sc.nextLine()); } 

它帮助我阅读ZIP的内容,而无需写入另一个文件。

ZipInputStream本身就是一个InputStream ,并在每次调用getNextEntry()之后传递每个条目的内容。 必须特别小心,不要关闭读取内容的流,因为它与ZIP流相同:

 public void readZipStream(InputStream in) throws IOException { ZipInputStream zipIn = new ZipInputStream(in); ZipEntry entry; while ((entry = zipIn.getNextEntry()) != null) { System.out.println(entry.getName()); readContents(zipIn); zipIn.closeEntry(); } } private void readContents(InputStream contentsIn) throws IOException { byte contents[] = new byte[4096]; int direct; while ((direct = contentsIn.read(contents, 0, contents.length)) >= 0) { System.out.println("Read " + direct + "bytes content."); } } 

将读取内容委托给其他逻辑时,可能需要使用FilterInputStream包装ZipInputStream以仅关闭条目而不是整个流,如下所示:

 public void readZipStream(InputStream in) throws IOException { ZipInputStream zipIn = new ZipInputStream(in); ZipEntry entry; while ((entry = zipIn.getNextEntry()) != null) { System.out.println(entry.getName()); readContents(new FilterInputStream(zipIn) { @Override public void close() throws IOException { zipIn.closeEntry(); } }); } }