-2

I have a piece of code for reading CSV file from a zipInputStream. I am trying to read all entries of this zipInputStream, so if there is txt, pdf. I don't need any of them, the zip file supposed to be impressed by one and only one CSV file, if not, throw an error.

int CSVFile = 0;
Scanner scanner = null;
String line = "";
while((entry = zipinputstream.getNextEntry())!=null){
  if(entry.getName.endsWith(".csv")){
    CSVFile += 1;
    scanner = new Scanner(zipinputstream);
  }
}
if(CSVFile > 1 || CSVFile == 0){
  throw new Exception("error");
}
if(scanner.hasNextLine()){
 System.out.println(scanner.nextLine()); 
} else {
  throw new Exception("there is no newline")
}

however I have tested this with a zip file impressed by a pdf and a CSV, CSV is not empty. it should print out a new line but it gives me "there is no newline". is there any logic issue I didn't see?

user207421
  • 305,947
  • 44
  • 307
  • 483
  • Is the CSV file empty? What does `jar -tvf` say about its length? What happens if you call `hasNextToken()` or `nextToken()`? What happens if you try to read from the `ZipInputStream` some other way? – user207421 Aug 16 '19 at 00:54
  • the csv file is not empty, the problem is i have use this logic and it works fine, now i just add a while loop and keep reading next entry then its broken, wondering if i used wrong logic. Of course i can use other way to do this, but that will not be the right answer for this bug. – Liming Kang Aug 16 '19 at 01:18
  • You have to read the file from inside the `while` loop when you find it., not after you've scanned the ZIP to the end. Or `break` when you find it in the `while` loop. – user207421 Aug 16 '19 at 02:33

1 Answers1

-1

Try this code. It accepts the path to your zip file and returns a byte array with the CSV file content inside it. If there are more files inside the ZIP or the CSV file is not found, then exceptions are thrown.

public byte[] readCSVFileAsInputStream(String filePath) {
  File file = new File(filePath);

  try (ZipFile zipFile = new ZipFile(file))
  {
     Enumeration<? extends ZipEntry> entries = zipFile.entries();
     ZipEntry entry = entries.nextElement();

     if(entry == null){
        throw new IllegalArgumentException("no files found inside: " + filePath);
     }

     if (entries.hasMoreElements())
     {
        throw new IllegalArgumentException("only one CSV file is accepted inside: " + filePath);
     }

     if (!FilenameUtils.getExtension(entry.getName()).equalsIgnoreCase("csv"))
     {
        throw new IllegalArgumentException("only one CSV file is accepted inside: " + filePath);
     }

     try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream())
     {
        IOUtils.copy(zipFile.getInputStream(entry), byteArrayOutputStream);
        return byteArrayOutputStream.toByteArray();
     }
  }
  catch (IOException exception)
  {
     throw new UncheckedIOException(MessageFormat.format("error while reading {0}", filePath), exception);
  }}
robingood
  • 319
  • 2
  • 10
  • The `ZipFile`, and therefore the `ZipInputStream`, are closed by the try-with-resources statement, which makes.the `ZipInputStream` useless outside the method. – user207421 Aug 16 '19 at 12:12
  • @user207421 thank you for your comment. Indeed, "Closing this ZIP file will, in turn, close all input streams that have been returned by invocations of this method." I have adapted the code accordingly. – robingood Aug 16 '19 at 12:43