Compressing a file using zip or gzip Write a Compress class defines two static methods, gzipFile(), which
  compresses a file using GZIP compression format, and zipDirectory(),
  which compresses the files (but not directories) in a directory using
  the ZIP archive and compression format. gzipFile() uses the
  GZIPOutputStream class, while zipDirectory() uses the ZipOutputStream
  and ZipEntry classes, all from java.util.zip.


I am outputting the compressed file in the same directory as the input file.
For zipDirectory() method I have recursively found out the files present in the directory(including those in the sub directories), stored them in a List&lt;File&gt;, and added them to the zip.
How can I improve this code?

package beg_assignment8;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.zip.GZIPOutputStream;
import java.util.zip.ZipOutputStream;
import java.util.zip.ZipEntry;

public class Compress {
    public static void main(String[] args) throws FileNotFoundException, IOException {
        Scanner sc = new Scanner(System.in);
        int op = sc.nextInt();
        String source = sc.next();
        switch (op) {
        case 1:
            GZIPFile(source);
            break;
        case 2:
            zipDirectory(source);
            break;
        }
    }

    public static void GZIPFile(String sourcePath) throws FileNotFoundException, IOException {
        File file = new File(sourcePath);
        String destPath = sourcePath + ".gz";


        try (
            FileOutputStream fos = new FileOutputStream(destPath);
            GZIPOutputStream gzos = new GZIPOutputStream(fos)
        ) {
            writeFileToOutputStream(file, gzos);
        }
    }

    public static void zipDirectory(String sourcePath) throws FileNotFoundException, IOException {
        File dir = new File(sourcePath);
        List&lt;File&gt; allFiles = getAllFiles(dir);
        String destPath = sourcePath + ".zip";

        try (
            FileOutputStream fos = new FileOutputStream(destPath);
            ZipOutputStream zos = new ZipOutputStream(fos)
        ) {
            for (File file : allFiles) {
                String zipFile =
                    file.getCanonicalPath().substring(dir.getCanonicalPath()
                            .length() + 1);
                ZipEntry ze = new ZipEntry(zipFile);
                zos.putNextEntry(ze);
                writeFileToOutputStream(file, zos);
                zos.closeEntry();
            }
        }
    }

    private static List&lt;File&gt; getAllFiles(File dir) {
        File[] files = dir.listFiles();
        List&lt;File&gt; allFiles = new ArrayList&lt;&gt;();
        for (File file : files) {
            if (file.isDirectory()) {
                List&lt;File&gt; allFilesRecur = getAllFiles(file);
                allFiles.addAll(allFilesRecur);
            } else {
                allFiles.add(file);
            }
        }
        return allFiles;
    }

    private static void writeFileToOutputStream(File file,
            OutputStream os) throws FileNotFoundException, IOException {
        try (
            FileInputStream fis = new FileInputStream(file);
            BufferedInputStream bis = new BufferedInputStream(fis)
        ) {
            byte[] buffer = new byte[1024];
            int nBytesRead;
            while ((nBytesRead = bis.read(buffer, 0, buffer.length)) &gt;= 0) {
                os.write(buffer);
            } 
        };
    }
}
nBytesRead ignored!


        int nBytesRead;
        while ((nBytesRead = bis.read(buffer, 0, buffer.length)) &gt;= 0) {
            os.write(buffer);
        }



You forgot to use the nBytesRead variable when writing to the other stream, putting garbage data in the target file.

        int nBytesRead;
        while ((nBytesRead = bis.read(buffer, 0, buffer.length)) &gt;= 0) {
            os.write(buffer, 0, nBytesRead);
        }


zipDirectory() throws a NPE

Your code throws a NullPointerException if the directory doesn't exists. (Caused by dir.listFiles(); returning null, failing the for loop after)

You should check if dir.exists is true, before continuing with the method, and throw a FileNotFoundException if it is false.

Possible IndexOutOfBoundsException


String zipFile = file.getCanonicalPath().substring(dir.getCanonicalPath()
                        .length() + 1);



While this line usually works correctly, it fails on unix systems if the file is symlinked to a directory with less characters, this will throw a IndexOutOfBoundsException