如何在不先创建 ZIP 文件的情况下在 Android 中创建 ZIP InputStream?

How to create a ZIP InputStream in Android without creating a ZIP file first?

我在我的AndroidAPP中使用NanoHTTPD作为Web服务器,我希望压缩一些文件并在服务器端创建一个InputStream,我在客户端使用代码A下载InputStream。

我已阅读 How to zip and unzip the files? 中的代码 B,但如何在 Android 中创建 ZIP 输入流而不先创建 ZIP 文件?

顺便说一句,我认为代码 C 不是一个好方法,因为它先制作 ZIP 文件,然后将 ZIP 文件转换为 FileInputStream ,我希望直接创建一个 ZIP InputStream!

代码A

private Response ActionDownloadSingleFile(InputStream fis)    {      
    Response response = null;
    response = newChunkedResponse(Response.Status.OK, "application/octet-stream",fis);
    response.addHeader("Content-Disposition", "attachment; filename="+"my.zip");
    return response;
}

代码B

public static void zip(String[] files, String zipFile) throws IOException {
    BufferedInputStream origin = null;
    ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFile)));
    try { 
        byte data[] = new byte[BUFFER_SIZE];

        for (int i = 0; i < files.length; i++) {
            FileInputStream fi = new FileInputStream(files[i]);    
            origin = new BufferedInputStream(fi, BUFFER_SIZE);
            try {
                ZipEntry entry = new ZipEntry(files[i].substring(files[i].lastIndexOf("/") + 1));
                out.putNextEntry(entry);
                int count;
                while ((count = origin.read(data, 0, BUFFER_SIZE)) != -1) {
                    out.write(data, 0, count);
                }
            }
            finally {
                origin.close();
            }
        }
    }
    finally {
        out.close();
    }
}

代码C

File file= new File("my.zip");
FileInputStream fis = null;
try
{
    fis = new FileInputStream(file);
} catch (FileNotFoundException ex)
{

}

ZipInputStream 根据文档 ZipInputStream

ZipInputStream is an input stream filter for reading files in the ZIP file format. Includes support for both compressed and uncompressed entries.

早些时候我回答这个问题的方式是无法使用 ZipInputStream。对不起。

But after investing some time I found that it is possible as per the below code

很明显,因为您发送的是 zip 格式的文件 通过网络。

//Create proper background thread pool. Not best but just for solution
new Thread(new Runnable() {
  @Override
  public void run() {

   // Moves the current Thread into the background
   android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);

    HttpURLConnection httpURLConnection = null;
    byte[] buffer = new byte[2048];
    try {
      //Your http connection
      httpURLConnection = (HttpURLConnection) new URL("https://s3-ap-southeast-1.amazonaws.com/uploads-ap.hipchat.com/107225/1251522/SFSCjI8ZRB7FjV9/zvsd.zip").openConnection();

      //Change below path to Environment.getExternalStorageDirectory() or something of your
      // own by creating storage utils
      File outputFilePath = new File  ("/mnt/sdcard/Android/data/somedirectory/");

      ZipInputStream zipInputStream = new ZipInputStream(new BufferedInputStream(httpURLConnection.getInputStream()));
      ZipEntry zipEntry = zipInputStream.getNextEntry();

      int readLength;

      while(zipEntry != null){
        File newFile = new File(outputFilePath, zipEntry.getName());

        if (!zipEntry.isDirectory()) {
          FileOutputStream fos = new FileOutputStream(newFile);
          while ((readLength = zipInputStream.read(buffer)) > 0) {
            fos.write(buffer, 0, readLength);
          }
          fos.close();
        } else {
          newFile.mkdirs();
        }

        Log.i("zip file path = ", newFile.getPath());
        zipInputStream.closeEntry();
        zipEntry = zipInputStream.getNextEntry();
      }
      // Close Stream and disconnect HTTP connection. Move to finally
      zipInputStream.closeEntry();
      zipInputStream.close();
    } catch (IOException e) {
      e.printStackTrace();
    }finally {
      // Close Stream and disconnect HTTP connection.
      if (httpURLConnection != null) {
        httpURLConnection.disconnect();
      }
    }
  }
}).start();