/* * Copyright 2010 Srikanth Reddy Lingala * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.lingala.zip4j.util; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.RandomAccessFile; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.HashMap; import net.lingala.zip4j.core.HeaderReader; import net.lingala.zip4j.core.HeaderWriter; import net.lingala.zip4j.exception.ZipException; import net.lingala.zip4j.io.SplitOutputStream; import net.lingala.zip4j.model.FileHeader; import net.lingala.zip4j.model.LocalFileHeader; import net.lingala.zip4j.model.Zip64EndCentralDirLocator; import net.lingala.zip4j.model.Zip64EndCentralDirRecord; import net.lingala.zip4j.model.ZipModel; import net.lingala.zip4j.progress.ProgressMonitor; public class ArchiveMaintainer { public ArchiveMaintainer() { } public HashMap removeZipFile(final ZipModel zipModel, final FileHeader fileHeader, final ProgressMonitor progressMonitor, boolean runInThread) throws ZipException { if (runInThread) { Thread thread = new Thread(InternalZipConstants.THREAD_NAME) { public void run() { try { initRemoveZipFile(zipModel, fileHeader, progressMonitor); progressMonitor.endProgressMonitorSuccess(); } catch (ZipException e) { } } }; thread.start(); return null; } else { HashMap retMap = initRemoveZipFile(zipModel, fileHeader, progressMonitor); progressMonitor.endProgressMonitorSuccess(); return retMap; } } public HashMap initRemoveZipFile(ZipModel zipModel, FileHeader fileHeader, ProgressMonitor progressMonitor) throws ZipException { if (fileHeader == null || zipModel == null) { throw new ZipException("input parameters is null in maintain zip file, cannot remove file from archive"); } OutputStream outputStream = null; File zipFile = null; RandomAccessFile inputStream = null; boolean successFlag = false; String tmpZipFileName = null; HashMap retMap = new HashMap(); try { int indexOfFileHeader = Zip4jUtil.getIndexOfFileHeader(zipModel, fileHeader); if (indexOfFileHeader < 0) { throw new ZipException("file header not found in zip model, cannot remove file"); } if (zipModel.isSplitArchive()) { throw new ZipException("This is a split archive. Zip file format does not allow updating split/spanned files"); } long currTime = System.currentTimeMillis(); tmpZipFileName = zipModel.getZipFile() + currTime%1000; File tmpFile = new File(tmpZipFileName); while (tmpFile.exists()) { currTime = System.currentTimeMillis(); tmpZipFileName = zipModel.getZipFile() + currTime%1000; tmpFile = new File(tmpZipFileName); } try { outputStream = new SplitOutputStream(new File(tmpZipFileName)); } catch (FileNotFoundException e1) { throw new ZipException(e1); } zipFile = new File(zipModel.getZipFile()); inputStream = createFileHandler(zipModel, InternalZipConstants.READ_MODE); HeaderReader headerReader = new HeaderReader(inputStream); LocalFileHeader localFileHeader = headerReader.readLocalFileHeader(fileHeader); if (localFileHeader == null) { throw new ZipException("invalid local file header, cannot remove file from archive"); } long offsetLocalFileHeader = fileHeader.getOffsetLocalHeader(); if (fileHeader.getZip64ExtendedInfo() != null && fileHeader.getZip64ExtendedInfo().getOffsetLocalHeader() != -1) { offsetLocalFileHeader = fileHeader.getZip64ExtendedInfo().getOffsetLocalHeader(); } long offsetEndOfCompressedFile = -1; long offsetStartCentralDir = zipModel.getEndCentralDirRecord().getOffsetOfStartOfCentralDir(); if (zipModel.isZip64Format()) { if (zipModel.getZip64EndCentralDirRecord() != null) { offsetStartCentralDir = zipModel.getZip64EndCentralDirRecord().getOffsetStartCenDirWRTStartDiskNo(); } } ArrayList fileHeaderList = zipModel.getCentralDirectory().getFileHeaders(); if (indexOfFileHeader == fileHeaderList.size() - 1) { offsetEndOfCompressedFile = offsetStartCentralDir - 1; } else { FileHeader nextFileHeader = (FileHeader)fileHeaderList.get(indexOfFileHeader + 1); if (nextFileHeader != null) { offsetEndOfCompressedFile = nextFileHeader.getOffsetLocalHeader() - 1; if (nextFileHeader.getZip64ExtendedInfo() != null && nextFileHeader.getZip64ExtendedInfo().getOffsetLocalHeader() != -1) { offsetEndOfCompressedFile = nextFileHeader.getZip64ExtendedInfo().getOffsetLocalHeader() - 1; } } } if (offsetLocalFileHeader < 0 || offsetEndOfCompressedFile < 0) { throw new ZipException("invalid offset for start and end of local file, cannot remove file"); } if(indexOfFileHeader == 0) { if (zipModel.getCentralDirectory().getFileHeaders().size() > 1) { // if this is the only file and it is deleted then no need to do this copyFile(inputStream, outputStream, offsetEndOfCompressedFile + 1, offsetStartCentralDir, progressMonitor); } } else if (indexOfFileHeader == fileHeaderList.size() - 1) { copyFile(inputStream, outputStream, 0, offsetLocalFileHeader, progressMonitor); } else { copyFile(inputStream, outputStream, 0, offsetLocalFileHeader, progressMonitor); copyFile(inputStream, outputStream, offsetEndOfCompressedFile + 1, offsetStartCentralDir, progressMonitor); } if (progressMonitor.isCancelAllTasks()) { progressMonitor.setResult(ProgressMonitor.RESULT_CANCELLED); progressMonitor.setState(ProgressMonitor.STATE_READY); return null; } zipModel.getEndCentralDirRecord().setOffsetOfStartOfCentralDir(((SplitOutputStream)outputStream).getFilePointer()); zipModel.getEndCentralDirRecord().setTotNoOfEntriesInCentralDir( zipModel.getEndCentralDirRecord().getTotNoOfEntriesInCentralDir() - 1); zipModel.getEndCentralDirRecord().setTotNoOfEntriesInCentralDirOnThisDisk( zipModel.getEndCentralDirRecord().getTotNoOfEntriesInCentralDirOnThisDisk() - 1); zipModel.getCentralDirectory().getFileHeaders().remove(indexOfFileHeader); for (int i = indexOfFileHeader; i < zipModel.getCentralDirectory().getFileHeaders().size(); i++) { long offsetLocalHdr = ((FileHeader)zipModel.getCentralDirectory().getFileHeaders().get(i)).getOffsetLocalHeader(); if (((FileHeader)zipModel.getCentralDirectory().getFileHeaders().get(i)).getZip64ExtendedInfo() != null && ((FileHeader)zipModel.getCentralDirectory().getFileHeaders().get(i)).getZip64ExtendedInfo().getOffsetLocalHeader() != -1) { offsetLocalHdr = ((FileHeader)zipModel.getCentralDirectory().getFileHeaders().get(i)).getZip64ExtendedInfo().getOffsetLocalHeader(); } ((FileHeader)zipModel.getCentralDirectory().getFileHeaders().get(i)).setOffsetLocalHeader( offsetLocalHdr - (offsetEndOfCompressedFile - offsetLocalFileHeader) - 1); } HeaderWriter headerWriter = new HeaderWriter(); headerWriter.finalizeZipFile(zipModel, outputStream); successFlag = true; retMap.put(InternalZipConstants.OFFSET_CENTRAL_DIR, Long.toString(zipModel.getEndCentralDirRecord().getOffsetOfStartOfCentralDir())); } catch (ZipException e) { progressMonitor.endProgressMonitorError(e); throw e; } catch (Exception e) { progressMonitor.endProgressMonitorError(e); throw new ZipException(e); } finally { try { if (inputStream != null) inputStream.close(); if (outputStream != null) outputStream.close(); } catch (IOException e) { throw new ZipException("cannot close input stream or output stream when trying to delete a file from zip file"); } if (successFlag) { restoreFileName(zipFile, tmpZipFileName); } else { File newZipFile = new File(tmpZipFileName); newZipFile.delete(); } } return retMap; } private void restoreFileName(File zipFile, String tmpZipFileName) throws ZipException { if (zipFile.delete()) { File newZipFile = new File(tmpZipFileName); if (!newZipFile.renameTo(zipFile)) { throw new ZipException("cannot rename modified zip file"); } } else { throw new ZipException("cannot delete old zip file"); } } private void copyFile(RandomAccessFile inputStream, OutputStream outputStream, long start, long end, ProgressMonitor progressMonitor) throws ZipException { if (inputStream == null || outputStream == null) { throw new ZipException("input or output stream is null, cannot copy file"); } if (start < 0) { throw new ZipException("starting offset is negative, cannot copy file"); } if (end < 0) { throw new ZipException("end offset is negative, cannot copy file"); } if (start > end) { throw new ZipException("start offset is greater than end offset, cannot copy file"); } if (start == end) { return; } if (progressMonitor.isCancelAllTasks()) { progressMonitor.setResult(ProgressMonitor.RESULT_CANCELLED); progressMonitor.setState(ProgressMonitor.STATE_READY); return; } try { inputStream.seek(start); int readLen = -2; byte[] buff; long bytesRead = 0; long bytesToRead = end - start; if ((end - start) < InternalZipConstants.BUFF_SIZE) { buff = new byte[(int)(end - start)]; } else { buff = new byte[InternalZipConstants.BUFF_SIZE]; } while ((readLen = inputStream.read(buff)) != -1) { outputStream.write(buff, 0, readLen); progressMonitor.updateWorkCompleted(readLen); if (progressMonitor.isCancelAllTasks()) { progressMonitor.setResult(ProgressMonitor.RESULT_CANCELLED); return; } bytesRead += readLen; if(bytesRead == bytesToRead) { break; } else if (bytesRead + buff.length > bytesToRead) { buff = new byte[(int)(bytesToRead - bytesRead)]; } } } catch (IOException e) { throw new ZipException(e); } catch (Exception e) { throw new ZipException(e); } } private RandomAccessFile createFileHandler(ZipModel zipModel, String mode) throws ZipException { if (zipModel == null || !Zip4jUtil.isStringNotNullAndNotEmpty(zipModel.getZipFile())) { throw new ZipException("input parameter is null in getFilePointer, cannot create file handler to remove file"); } try { return new RandomAccessFile(new File(zipModel.getZipFile()), mode); } catch (FileNotFoundException e) { throw new ZipException(e); } } /** * Merges split Zip files into a single Zip file * @param zipModel * @throws ZipException */ public void mergeSplitZipFiles(final ZipModel zipModel, final File outputZipFile, final ProgressMonitor progressMonitor, boolean runInThread) throws ZipException { if (runInThread) { Thread thread = new Thread(InternalZipConstants.THREAD_NAME) { public void run() { try { initMergeSplitZipFile(zipModel, outputZipFile, progressMonitor); } catch (ZipException e) { } } }; thread.start(); } else { initMergeSplitZipFile(zipModel, outputZipFile, progressMonitor); } } private void initMergeSplitZipFile(ZipModel zipModel, File outputZipFile, ProgressMonitor progressMonitor) throws ZipException { if (zipModel == null) { ZipException e = new ZipException("one of the input parameters is null, cannot merge split zip file"); progressMonitor.endProgressMonitorError(e); throw e; } if (!zipModel.isSplitArchive()) { ZipException e = new ZipException("archive not a split zip file"); progressMonitor.endProgressMonitorError(e); throw e; } OutputStream outputStream = null; RandomAccessFile inputStream = null; ArrayList fileSizeList = new ArrayList(); long totBytesWritten = 0; boolean splitSigRemoved = false; try { int totNoOfSplitFiles = zipModel.getEndCentralDirRecord().getNoOfThisDisk(); if (totNoOfSplitFiles <= 0) { throw new ZipException("corrupt zip model, archive not a split zip file"); } outputStream = prepareOutputStreamForMerge(outputZipFile); for (int i = 0; i <= totNoOfSplitFiles; i++) { inputStream = createSplitZipFileHandler(zipModel, i); int start = 0; Long end = new Long(inputStream.length()); if (i == 0) { if (zipModel.getCentralDirectory() != null && zipModel.getCentralDirectory().getFileHeaders() != null && zipModel.getCentralDirectory().getFileHeaders().size() > 0) { byte[] buff = new byte[4]; inputStream.seek(0); inputStream.read(buff); if (Raw.readIntLittleEndian(buff, 0) == InternalZipConstants.SPLITSIG) { start = 4; splitSigRemoved = true; } } } if (i == totNoOfSplitFiles) { end = new Long(zipModel.getEndCentralDirRecord().getOffsetOfStartOfCentralDir()); } copyFile(inputStream, outputStream, start, end.longValue(), progressMonitor); totBytesWritten += (end.longValue() - start); if (progressMonitor.isCancelAllTasks()) { progressMonitor.setResult(ProgressMonitor.RESULT_CANCELLED); progressMonitor.setState(ProgressMonitor.STATE_READY); return; } fileSizeList.add(end); try { inputStream.close(); } catch (IOException e) { //ignore } } ZipModel newZipModel = (ZipModel)zipModel.clone(); newZipModel.getEndCentralDirRecord().setOffsetOfStartOfCentralDir(totBytesWritten); updateSplitZipModel(newZipModel, fileSizeList, splitSigRemoved); HeaderWriter headerWriter = new HeaderWriter(); headerWriter.finalizeZipFileWithoutValidations(newZipModel, outputStream); progressMonitor.endProgressMonitorSuccess(); } catch (IOException e) { progressMonitor.endProgressMonitorError(e); throw new ZipException(e); } catch (Exception e) { progressMonitor.endProgressMonitorError(e); throw new ZipException(e); } finally { if (outputStream != null) { try { outputStream.close(); } catch (IOException e) { //ignore } } if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { // ignore } } } } /** * Creates an input stream for the split part of the zip file * @return Zip4jInputStream * @throws ZipException */ private RandomAccessFile createSplitZipFileHandler(ZipModel zipModel, int partNumber) throws ZipException { if (zipModel == null) { throw new ZipException("zip model is null, cannot create split file handler"); } if (partNumber < 0) { throw new ZipException("invlaid part number, cannot create split file handler"); } try { String curZipFile = zipModel.getZipFile(); String partFile = null; if (partNumber == zipModel.getEndCentralDirRecord().getNoOfThisDisk()) { partFile = zipModel.getZipFile(); } else { if (partNumber >= 9) { partFile = curZipFile.substring(0, curZipFile.lastIndexOf(".")) + ".z" + (partNumber+ 1); } else{ partFile = curZipFile.substring(0, curZipFile.lastIndexOf(".")) + ".z0" + (partNumber+ 1); } } File tmpFile = new File(partFile); if (!Zip4jUtil.checkFileExists(tmpFile)) { throw new ZipException("split file does not exist: " + partFile); } return new RandomAccessFile(tmpFile, InternalZipConstants.READ_MODE); } catch (FileNotFoundException e) { throw new ZipException(e); } catch (Exception e) { throw new ZipException(e); } } private OutputStream prepareOutputStreamForMerge(File outFile) throws ZipException { if (outFile == null) { throw new ZipException("outFile is null, cannot create outputstream"); } try { return new FileOutputStream(outFile); } catch (FileNotFoundException e) { throw new ZipException(e); } catch (Exception e) { throw new ZipException(e); } } private void updateSplitZipModel(ZipModel zipModel, ArrayList fileSizeList, boolean splitSigRemoved) throws ZipException { if (zipModel == null) { throw new ZipException("zip model is null, cannot update split zip model"); } zipModel.setSplitArchive(false); updateSplitFileHeader(zipModel, fileSizeList, splitSigRemoved); updateSplitEndCentralDirectory(zipModel); if (zipModel.isZip64Format()) { updateSplitZip64EndCentralDirLocator(zipModel, fileSizeList); updateSplitZip64EndCentralDirRec(zipModel, fileSizeList); } } private void updateSplitFileHeader(ZipModel zipModel, ArrayList fileSizeList, boolean splitSigRemoved) throws ZipException { try { if (zipModel.getCentralDirectory()== null) { throw new ZipException("corrupt zip model - getCentralDirectory, cannot update split zip model"); } int fileHeaderCount = zipModel.getCentralDirectory().getFileHeaders().size(); int splitSigOverhead = 0; if (splitSigRemoved) splitSigOverhead = 4; for (int i = 0; i < fileHeaderCount; i++) { long offsetLHToAdd = 0; for (int j = 0; j < ((FileHeader)zipModel.getCentralDirectory().getFileHeaders().get(i)).getDiskNumberStart(); j++) { offsetLHToAdd += ((Long)fileSizeList.get(j)).longValue(); } ((FileHeader)zipModel.getCentralDirectory().getFileHeaders().get(i)).setOffsetLocalHeader( ((FileHeader)zipModel.getCentralDirectory().getFileHeaders().get(i)).getOffsetLocalHeader() + offsetLHToAdd - splitSigOverhead); ((FileHeader)zipModel.getCentralDirectory().getFileHeaders().get(i)).setDiskNumberStart(0); } } catch (ZipException e) { throw e; } catch (Exception e) { throw new ZipException(e); } } private void updateSplitEndCentralDirectory(ZipModel zipModel) throws ZipException { try { if (zipModel == null) { throw new ZipException("zip model is null - cannot update end of central directory for split zip model"); } if (zipModel.getCentralDirectory()== null) { throw new ZipException("corrupt zip model - getCentralDirectory, cannot update split zip model"); } zipModel.getEndCentralDirRecord().setNoOfThisDisk(0); zipModel.getEndCentralDirRecord().setNoOfThisDiskStartOfCentralDir(0); zipModel.getEndCentralDirRecord().setTotNoOfEntriesInCentralDir( zipModel.getCentralDirectory().getFileHeaders().size()); zipModel.getEndCentralDirRecord().setTotNoOfEntriesInCentralDirOnThisDisk( zipModel.getCentralDirectory().getFileHeaders().size()); } catch (ZipException e) { throw e; } catch (Exception e) { throw new ZipException(e); } } private void updateSplitZip64EndCentralDirLocator(ZipModel zipModel, ArrayList fileSizeList) throws ZipException { if (zipModel == null) { throw new ZipException("zip model is null, cannot update split Zip64 end of central directory locator"); } if (zipModel.getZip64EndCentralDirLocator() == null) { return; } zipModel.getZip64EndCentralDirLocator().setNoOfDiskStartOfZip64EndOfCentralDirRec(0); long offsetZip64EndCentralDirRec = 0; for (int i = 0; i < fileSizeList.size(); i++) { offsetZip64EndCentralDirRec += ((Long)fileSizeList.get(i)).longValue(); } zipModel.getZip64EndCentralDirLocator().setOffsetZip64EndOfCentralDirRec( ((Zip64EndCentralDirLocator)zipModel.getZip64EndCentralDirLocator()).getOffsetZip64EndOfCentralDirRec() + offsetZip64EndCentralDirRec); zipModel.getZip64EndCentralDirLocator().setTotNumberOfDiscs(1); } private void updateSplitZip64EndCentralDirRec(ZipModel zipModel, ArrayList fileSizeList) throws ZipException { if (zipModel == null) { throw new ZipException("zip model is null, cannot update split Zip64 end of central directory record"); } if (zipModel.getZip64EndCentralDirRecord() == null) { return; } zipModel.getZip64EndCentralDirRecord().setNoOfThisDisk(0); zipModel.getZip64EndCentralDirRecord().setNoOfThisDiskStartOfCentralDir(0); zipModel.getZip64EndCentralDirRecord().setTotNoOfEntriesInCentralDirOnThisDisk( zipModel.getEndCentralDirRecord().getTotNoOfEntriesInCentralDir()); long offsetStartCenDirWRTStartDiskNo = 0; for (int i = 0; i < fileSizeList.size(); i++) { offsetStartCenDirWRTStartDiskNo += ((Long)fileSizeList.get(i)).longValue(); } zipModel.getZip64EndCentralDirRecord().setOffsetStartCenDirWRTStartDiskNo( ((Zip64EndCentralDirRecord)zipModel.getZip64EndCentralDirRecord()).getOffsetStartCenDirWRTStartDiskNo() + offsetStartCenDirWRTStartDiskNo); } public void setComment(ZipModel zipModel, String comment) throws ZipException { if (comment == null) { throw new ZipException("comment is null, cannot update Zip file with comment"); } if (zipModel == null) { throw new ZipException("zipModel is null, cannot update Zip file with comment"); } String encodedComment = comment; byte[] commentBytes = comment.getBytes(); int commentLength = comment.length(); if (Zip4jUtil.isSupportedCharset(InternalZipConstants.CHARSET_COMMENTS_DEFAULT)) { try { encodedComment = new String(comment.getBytes(InternalZipConstants.CHARSET_COMMENTS_DEFAULT), InternalZipConstants.CHARSET_COMMENTS_DEFAULT); commentBytes = encodedComment.getBytes(InternalZipConstants.CHARSET_COMMENTS_DEFAULT); commentLength = encodedComment.length(); } catch (UnsupportedEncodingException e) { encodedComment = comment; commentBytes = comment.getBytes(); commentLength = comment.length(); } } if (commentLength > InternalZipConstants.MAX_ALLOWED_ZIP_COMMENT_LENGTH) { throw new ZipException("comment length exceeds maximum length"); } zipModel.getEndCentralDirRecord().setComment(encodedComment); zipModel.getEndCentralDirRecord().setCommentBytes(commentBytes); zipModel.getEndCentralDirRecord().setCommentLength(commentLength); SplitOutputStream outputStream = null; try { HeaderWriter headerWriter = new HeaderWriter(); outputStream = new SplitOutputStream(zipModel.getZipFile()); if (zipModel.isZip64Format()) { outputStream.seek(zipModel.getZip64EndCentralDirRecord().getOffsetStartCenDirWRTStartDiskNo()); } else { outputStream.seek(zipModel.getEndCentralDirRecord().getOffsetOfStartOfCentralDir()); } headerWriter.finalizeZipFileWithoutValidations(zipModel, outputStream); } catch (FileNotFoundException e) { throw new ZipException(e); } catch (IOException e) { throw new ZipException(e); } finally { if (outputStream != null) { try { outputStream.close(); } catch (IOException e) { //ignore } } } } public void initProgressMonitorForRemoveOp(ZipModel zipModel, FileHeader fileHeader, ProgressMonitor progressMonitor) throws ZipException { if (zipModel == null || fileHeader == null || progressMonitor == null) { throw new ZipException("one of the input parameters is null, cannot calculate total work"); } progressMonitor.setCurrentOperation(ProgressMonitor.OPERATION_REMOVE); progressMonitor.setFileName(fileHeader.getFileName()); progressMonitor.setTotalWork(calculateTotalWorkForRemoveOp(zipModel, fileHeader)); progressMonitor.setState(ProgressMonitor.STATE_BUSY); } private long calculateTotalWorkForRemoveOp(ZipModel zipModel, FileHeader fileHeader) throws ZipException { return Zip4jUtil.getFileLengh(new File(zipModel.getZipFile())) - fileHeader.getCompressedSize(); } public void initProgressMonitorForMergeOp(ZipModel zipModel, ProgressMonitor progressMonitor) throws ZipException { if (zipModel == null) { throw new ZipException("zip model is null, cannot calculate total work for merge op"); } progressMonitor.setCurrentOperation(ProgressMonitor.OPERATION_MERGE); progressMonitor.setFileName(zipModel.getZipFile()); progressMonitor.setTotalWork(calculateTotalWorkForMergeOp(zipModel)); progressMonitor.setState(ProgressMonitor.STATE_BUSY); } private long calculateTotalWorkForMergeOp(ZipModel zipModel) throws ZipException { long totSize = 0; if (zipModel.isSplitArchive()) { int totNoOfSplitFiles = zipModel.getEndCentralDirRecord().getNoOfThisDisk(); String partFile = null; String curZipFile = zipModel.getZipFile(); int partNumber = 0; for (int i = 0; i <= totNoOfSplitFiles; i++) { if (partNumber == zipModel.getEndCentralDirRecord().getNoOfThisDisk()) { partFile = zipModel.getZipFile(); } else { if (partNumber >= 9) { partFile = curZipFile.substring(0, curZipFile.lastIndexOf(".")) + ".z" + (partNumber+ 1); } else{ partFile = curZipFile.substring(0, curZipFile.lastIndexOf(".")) + ".z0" + (partNumber+ 1); } } totSize += Zip4jUtil.getFileLengh(new File(partFile)); } } return totSize; } }