Java 如何在Android中创建ZIP输入流而不首先创建ZIP文件?

Java 如何在Android中创建ZIP输入流而不首先创建ZIP文件?,java,android,zipfile,fileinputstream,fileoutputstream,Java,Android,Zipfile,Fileinputstream,Fileoutputstream,我在Android应用程序中使用NanoHTTPD作为web服务器,我希望在服务器端压缩一些文件并创建一个InputStream,然后在客户端使用代码a下载InputStream 我已经阅读了代码B,但是如何在Android中创建ZIP输入流而不首先创建ZIP文件呢 顺便说一句,我认为代码C不是一个好方法,因为它先生成ZIP文件,然后将ZIP文件转换为FileInputStream,我希望直接创建一个ZIP InputStream 代码A private Response ActionDownl

我在Android应用程序中使用NanoHTTPD作为web服务器,我希望在服务器端压缩一些文件并创建一个InputStream,然后在客户端使用代码a下载InputStream

我已经阅读了代码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();
    }
}

ZipInputStream符合文档要求

ZipInputStream是一个输入流过滤器,用于读取ZIP文件格式的文件。包括对压缩和未压缩项的支持

早些时候,我以一种不可能使用
ZipInputStream
的方式回答了这个问题。对不起

但经过一段时间的投资后,我发现根据以下代码,这是可能的

很明显,因为您是以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();

您需要在服务器中创建一个输出流。一个
ZipOutputStream
,围绕着服务器技术提供给您的任何输出流。谢谢!对于EJP,你能给我一些示例代码吗?你不能直接生成ZipInputSteam,因为ZipInputSteam扩展了FilterInputStream,所以它基本上是一个包装类,为流提供读取zip文件的功能。您将需要类似于
newzipinputstream(newfileinputstream(zipFile))
的东西,谢谢!对Jonah Sloan来说,你的意思是我必须先创建ZIP文件,然后从ZIP文件中获取InputStream吗?如果我理解正确,代码A是您的服务器端代码,您可以提供迄今为止您拥有的客户端代码吗?@HelloCW如果您尝试过,请告诉我,因为它可以按照所需的输出正常工作。然而,它需要在关闭流方面进行一些优化。
//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();