1 | /*
|
---|
2 | Copyright (C) 2005-2014 Sergey A. Tachenov
|
---|
3 |
|
---|
4 | This file is part of QuaZIP test suite.
|
---|
5 |
|
---|
6 | QuaZIP is free software: you can redistribute it and/or modify
|
---|
7 | it under the terms of the GNU Lesser General Public License as published by
|
---|
8 | the Free Software Foundation, either version 2.1 of the License, or
|
---|
9 | (at your option) any later version.
|
---|
10 |
|
---|
11 | QuaZIP is distributed in the hope that it will be useful,
|
---|
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
14 | GNU Lesser General Public License for more details.
|
---|
15 |
|
---|
16 | You should have received a copy of the GNU Lesser General Public License
|
---|
17 | along with QuaZIP. If not, see <http://www.gnu.org/licenses/>.
|
---|
18 |
|
---|
19 | See COPYING file for the full LGPL text.
|
---|
20 |
|
---|
21 | Original ZIP package is copyrighted by Gilles Vollant and contributors,
|
---|
22 | see quazip/(un)zip.h files for details. Basically it's the zlib license.
|
---|
23 | */
|
---|
24 |
|
---|
25 | #include "testquazip.h"
|
---|
26 |
|
---|
27 | #include "qztest.h"
|
---|
28 |
|
---|
29 | #include <QDataStream>
|
---|
30 | #include <QDir>
|
---|
31 | #include <QFileInfo>
|
---|
32 | #include <QHash>
|
---|
33 | #ifdef QUAZIP_TEST_QSAVEFILE
|
---|
34 | #include <QSaveFile>
|
---|
35 | #endif
|
---|
36 | #include <QTcpServer>
|
---|
37 | #include <QTcpSocket>
|
---|
38 | #include <QTextCodec>
|
---|
39 |
|
---|
40 | #include <QtTest/QtTest>
|
---|
41 |
|
---|
42 | #include <quazip/quazip.h>
|
---|
43 | #include <quazip/JlCompress.h>
|
---|
44 |
|
---|
45 | void TestQuaZip::getFileList_data()
|
---|
46 | {
|
---|
47 | QTest::addColumn<QString>("zipName");
|
---|
48 | QTest::addColumn<QStringList>("fileNames");
|
---|
49 | QTest::newRow("simple") << "qzfilelist.zip" << (
|
---|
50 | QStringList() << "test0.txt" << "testdir1/test1.txt"
|
---|
51 | << "testdir2/test2.txt" << "testdir2/subdir/test2sub.txt");
|
---|
52 | QTest::newRow("russian") << QString::fromUtf8("файл.zip") << (
|
---|
53 | QStringList() << QString::fromUtf8("test0.txt") << QString::fromUtf8("test1/test1.txt")
|
---|
54 | << "testdir2/test2.txt" << "testdir2/subdir/test2sub.txt");
|
---|
55 | QTest::newRow("japanese") << QString::fromUtf8("テスト.zip") << (
|
---|
56 | QStringList() << QString::fromUtf8("test.txt"));
|
---|
57 | QTest::newRow("hebrew") << QString::fromUtf8("פתח תקווה.zip") << (
|
---|
58 | QStringList() << QString::fromUtf8("test.txt"));
|
---|
59 | }
|
---|
60 |
|
---|
61 | void TestQuaZip::getFileList()
|
---|
62 | {
|
---|
63 | QFETCH(QString, zipName);
|
---|
64 | QFETCH(QStringList, fileNames);
|
---|
65 | qSort(fileNames);
|
---|
66 | QDir curDir;
|
---|
67 | if (curDir.exists(zipName)) {
|
---|
68 | if (!curDir.remove(zipName))
|
---|
69 | QFAIL("Can't remove zip file");
|
---|
70 | }
|
---|
71 | if (!createTestFiles(fileNames)) {
|
---|
72 | QFAIL("Can't create test file");
|
---|
73 | }
|
---|
74 | if (!createTestArchive(zipName, fileNames)) {
|
---|
75 | QFAIL("Can't create test archive");
|
---|
76 | }
|
---|
77 | QuaZip testZip(zipName);
|
---|
78 | QVERIFY(testZip.open(QuaZip::mdUnzip));
|
---|
79 | QVERIFY(testZip.goToFirstFile());
|
---|
80 | QString firstFile = testZip.getCurrentFileName();
|
---|
81 | QStringList fileList = testZip.getFileNameList();
|
---|
82 | qSort(fileList);
|
---|
83 | QCOMPARE(fileList, fileNames);
|
---|
84 | QHash<QString, QFileInfo> srcInfo;
|
---|
85 | foreach (QString fileName, fileNames) {
|
---|
86 | srcInfo[fileName] = QFileInfo("tmp/" + fileName);
|
---|
87 | }
|
---|
88 | QList<QuaZipFileInfo> destList = testZip.getFileInfoList();
|
---|
89 | QCOMPARE(destList.size(), srcInfo.size());
|
---|
90 | for (int i = 0; i < destList.size(); i++) {
|
---|
91 | QCOMPARE(static_cast<qint64>(destList[i].uncompressedSize),
|
---|
92 | srcInfo[destList[i].name].size());
|
---|
93 | }
|
---|
94 | // Now test zip64
|
---|
95 | QList<QuaZipFileInfo64> destList64 = testZip.getFileInfoList64();
|
---|
96 | QCOMPARE(destList64.size(), srcInfo.size());
|
---|
97 | for (int i = 0; i < destList64.size(); i++) {
|
---|
98 | QCOMPARE(static_cast<qint64>(destList64[i].uncompressedSize),
|
---|
99 | srcInfo[destList64[i].name].size());
|
---|
100 | }
|
---|
101 | // test that we didn't mess up the current file
|
---|
102 | QCOMPARE(testZip.getCurrentFileName(), firstFile);
|
---|
103 | testZip.close();
|
---|
104 | // clean up
|
---|
105 | removeTestFiles(fileNames);
|
---|
106 | curDir.remove(zipName);
|
---|
107 | }
|
---|
108 |
|
---|
109 | void TestQuaZip::add_data()
|
---|
110 | {
|
---|
111 | QTest::addColumn<QString>("zipName");
|
---|
112 | QTest::addColumn<QStringList>("fileNames");
|
---|
113 | QTest::addColumn<QStringList>("fileNamesToAdd");
|
---|
114 | QTest::newRow("simple") << "qzadd.zip" << (
|
---|
115 | QStringList() << "test0.txt" << "testdir1/test1.txt"
|
---|
116 | << "testdir2/test2.txt" << "testdir2/subdir/test2sub.txt")
|
---|
117 | << (QStringList() << "testAdd.txt");
|
---|
118 | }
|
---|
119 |
|
---|
120 | void TestQuaZip::add()
|
---|
121 | {
|
---|
122 | QFETCH(QString, zipName);
|
---|
123 | QFETCH(QStringList, fileNames);
|
---|
124 | QFETCH(QStringList, fileNamesToAdd);
|
---|
125 | QDir curDir;
|
---|
126 | if (curDir.exists(zipName)) {
|
---|
127 | if (!curDir.remove(zipName))
|
---|
128 | QFAIL("Can't remove zip file");
|
---|
129 | }
|
---|
130 | if (!createTestFiles(fileNames)) {
|
---|
131 | QFAIL("Can't create test file");
|
---|
132 | }
|
---|
133 | if (!createTestArchive(zipName, fileNames)) {
|
---|
134 | QFAIL("Can't create test archive");
|
---|
135 | }
|
---|
136 | if (!createTestFiles(fileNamesToAdd)) {
|
---|
137 | QFAIL("Can't create test files to add");
|
---|
138 | }
|
---|
139 | QuaZip testZip(zipName);
|
---|
140 | QVERIFY(testZip.open(QuaZip::mdUnzip));
|
---|
141 | // according to the bug #3485459 the global is lost, so we test it
|
---|
142 | QString globalComment = testZip.getComment();
|
---|
143 | testZip.close();
|
---|
144 | QVERIFY(testZip.open(QuaZip::mdAdd));
|
---|
145 | foreach (QString fileName, fileNamesToAdd) {
|
---|
146 | QuaZipFile testFile(&testZip);
|
---|
147 | QVERIFY(testFile.open(QIODevice::WriteOnly,
|
---|
148 | QuaZipNewInfo(fileName, "tmp/" + fileName)));
|
---|
149 | QFile inFile("tmp/" + fileName);
|
---|
150 | QVERIFY(inFile.open(QIODevice::ReadOnly));
|
---|
151 | testFile.write(inFile.readAll());
|
---|
152 | inFile.close();
|
---|
153 | testFile.close();
|
---|
154 | }
|
---|
155 | testZip.close();
|
---|
156 | QVERIFY(testZip.open(QuaZip::mdUnzip));
|
---|
157 | QStringList allNames = fileNames + fileNamesToAdd;
|
---|
158 | QCOMPARE(testZip.getEntriesCount(), allNames.size());
|
---|
159 | QCOMPARE(testZip.getFileNameList(), allNames);
|
---|
160 | QCOMPARE(testZip.getComment(), globalComment);
|
---|
161 | testZip.close();
|
---|
162 | removeTestFiles(fileNames);
|
---|
163 | removeTestFiles(fileNamesToAdd);
|
---|
164 | curDir.remove(zipName);
|
---|
165 | }
|
---|
166 |
|
---|
167 | void TestQuaZip::setFileNameCodec_data()
|
---|
168 | {
|
---|
169 | QTest::addColumn<QString>("zipName");
|
---|
170 | QTest::addColumn<QStringList>("fileNames");
|
---|
171 | QTest::addColumn<QByteArray>("encoding");
|
---|
172 | QTest::newRow("russian") << QString::fromUtf8("russian.zip") << (
|
---|
173 | QStringList() << QString::fromUtf8("тест.txt")) << QByteArray("IBM866");
|
---|
174 | }
|
---|
175 |
|
---|
176 | void TestQuaZip::setFileNameCodec()
|
---|
177 | {
|
---|
178 | QFETCH(QString, zipName);
|
---|
179 | QFETCH(QStringList, fileNames);
|
---|
180 | QFETCH(QByteArray, encoding);
|
---|
181 | qSort(fileNames);
|
---|
182 | QDir curDir;
|
---|
183 | if (curDir.exists(zipName)) {
|
---|
184 | if (!curDir.remove(zipName))
|
---|
185 | QFAIL("Can't remove zip file");
|
---|
186 | }
|
---|
187 | if (!createTestFiles(fileNames)) {
|
---|
188 | QFAIL("Can't create test file");
|
---|
189 | }
|
---|
190 | if (!createTestArchive(zipName, fileNames,
|
---|
191 | QTextCodec::codecForName(encoding))) {
|
---|
192 | QFAIL("Can't create test archive");
|
---|
193 | }
|
---|
194 | QuaZip testZip(zipName);
|
---|
195 | QVERIFY(testZip.open(QuaZip::mdUnzip));
|
---|
196 | QStringList fileList = testZip.getFileNameList();
|
---|
197 | qSort(fileList);
|
---|
198 | QVERIFY(fileList[0] != fileNames[0]);
|
---|
199 | testZip.close();
|
---|
200 | testZip.setFileNameCodec(encoding);
|
---|
201 | QVERIFY(testZip.open(QuaZip::mdUnzip));
|
---|
202 | fileList = testZip.getFileNameList();
|
---|
203 | qSort(fileList);
|
---|
204 | QCOMPARE(fileList, fileNames);
|
---|
205 | testZip.close();
|
---|
206 | // clean up
|
---|
207 | removeTestFiles(fileNames);
|
---|
208 | curDir.remove(zipName);
|
---|
209 | }
|
---|
210 |
|
---|
211 | void TestQuaZip::setDataDescriptorWritingEnabled()
|
---|
212 | {
|
---|
213 | QString zipName = "zip10.zip";
|
---|
214 | QDir curDir;
|
---|
215 | if (curDir.exists(zipName)) {
|
---|
216 | if (!curDir.remove(zipName))
|
---|
217 | QFAIL("Can't remove zip file");
|
---|
218 | }
|
---|
219 | QuaZip testZip(zipName);
|
---|
220 | testZip.setDataDescriptorWritingEnabled(false);
|
---|
221 | QVERIFY(testZip.open(QuaZip::mdCreate));
|
---|
222 | QuaZipFile testZipFile(&testZip);
|
---|
223 | QVERIFY(testZipFile.open(QIODevice::WriteOnly,
|
---|
224 | QuaZipNewInfo("vegetation_info.xml"), NULL, 0, 0));
|
---|
225 | QByteArray contents = "<vegetation_info version=\"4096\" />\n";
|
---|
226 | testZipFile.write(contents);
|
---|
227 | testZipFile.close();
|
---|
228 | testZip.close();
|
---|
229 | QuaZipFile readZipFile(zipName, "vegetation_info.xml");
|
---|
230 | QVERIFY(readZipFile.open(QIODevice::ReadOnly));
|
---|
231 | // Test that file is not compressed.
|
---|
232 | QCOMPARE(readZipFile.csize(), static_cast<qint64>(contents.size()));
|
---|
233 | readZipFile.close();
|
---|
234 | QCOMPARE(QFileInfo(zipName).size(), static_cast<qint64>(171));
|
---|
235 | QFile zipFile(zipName);
|
---|
236 | QVERIFY(zipFile.open(QIODevice::ReadOnly));
|
---|
237 | QDataStream zipData(&zipFile);
|
---|
238 | zipData.setByteOrder(QDataStream::LittleEndian);
|
---|
239 | quint32 magic = 0;
|
---|
240 | quint16 versionNeeded = 0;
|
---|
241 | zipData >> magic;
|
---|
242 | zipData >> versionNeeded;
|
---|
243 | QCOMPARE(magic, static_cast<quint32>(0x04034b50));
|
---|
244 | QCOMPARE(versionNeeded, static_cast<quint16>(10));
|
---|
245 | zipFile.close();
|
---|
246 | curDir.remove(zipName);
|
---|
247 | // now test 2.0
|
---|
248 | zipName = "zip20.zip";
|
---|
249 | if (curDir.exists(zipName)) {
|
---|
250 | if (!curDir.remove(zipName))
|
---|
251 | QFAIL("Can't remove zip file");
|
---|
252 | }
|
---|
253 | QuaZip testZip20(zipName);
|
---|
254 | QVERIFY(testZip20.open(QuaZip::mdCreate));
|
---|
255 | QuaZipFile testZipFile20(&testZip20);
|
---|
256 | QVERIFY(testZipFile20.open(QIODevice::WriteOnly,
|
---|
257 | QuaZipNewInfo("vegetation_info.xml"), NULL, 0, 0));
|
---|
258 | testZipFile20.write("<vegetation_info version=\"4096\" />\n");
|
---|
259 | testZipFile20.close();
|
---|
260 | testZip20.close();
|
---|
261 | QCOMPARE(QFileInfo(zipName).size(),
|
---|
262 | static_cast<qint64>(171 + 16)); // 16 bytes = data descriptor
|
---|
263 | QFile zipFile20(zipName);
|
---|
264 | QVERIFY(zipFile20.open(QIODevice::ReadOnly));
|
---|
265 | QDataStream zipData20(&zipFile20);
|
---|
266 | zipData20.setByteOrder(QDataStream::LittleEndian);
|
---|
267 | magic = 0;
|
---|
268 | versionNeeded = 0;
|
---|
269 | zipData20 >> magic;
|
---|
270 | zipData20 >> versionNeeded;
|
---|
271 | QCOMPARE(magic, static_cast<quint32>(0x04034b50));
|
---|
272 | QCOMPARE(versionNeeded, static_cast<quint16>(20));
|
---|
273 | zipFile20.close();
|
---|
274 | curDir.remove(zipName);
|
---|
275 | }
|
---|
276 |
|
---|
277 | void TestQuaZip::testQIODeviceAPI()
|
---|
278 | {
|
---|
279 | QString zipName = "qiodevice_api.zip";
|
---|
280 | QStringList fileNames;
|
---|
281 | fileNames << "test.txt";
|
---|
282 | QDir curDir;
|
---|
283 | if (curDir.exists(zipName)) {
|
---|
284 | if (!curDir.remove(zipName))
|
---|
285 | QFAIL("Can't remove zip file");
|
---|
286 | }
|
---|
287 | if (!createTestFiles(fileNames)) {
|
---|
288 | QFAIL("Can't create test file");
|
---|
289 | }
|
---|
290 | if (!createTestArchive(zipName, fileNames)) {
|
---|
291 | QFAIL("Can't create test archive");
|
---|
292 | }
|
---|
293 | QBuffer buffer;
|
---|
294 | if (!createTestArchive(&buffer, fileNames, NULL)) {
|
---|
295 | QFAIL("Can't create test archive");
|
---|
296 | }
|
---|
297 | QFile diskFile(zipName);
|
---|
298 | QVERIFY(diskFile.open(QIODevice::ReadOnly));
|
---|
299 | QByteArray bufferArray = buffer.buffer();
|
---|
300 | QByteArray fileArray = diskFile.readAll();
|
---|
301 | diskFile.close();
|
---|
302 | QCOMPARE(bufferArray.size(), fileArray.size());
|
---|
303 | QCOMPARE(bufferArray, fileArray);
|
---|
304 | curDir.remove(zipName);
|
---|
305 | }
|
---|
306 |
|
---|
307 | void TestQuaZip::setZipName()
|
---|
308 | {
|
---|
309 | QuaZip zip;
|
---|
310 | zip.setZipName("testSetZipName.zip");
|
---|
311 | zip.open(QuaZip::mdCreate);
|
---|
312 | zip.close();
|
---|
313 | QVERIFY(QFileInfo(zip.getZipName()).exists());
|
---|
314 | QDir().remove(zip.getZipName());
|
---|
315 | }
|
---|
316 |
|
---|
317 | void TestQuaZip::setIoDevice()
|
---|
318 | {
|
---|
319 | QuaZip zip;
|
---|
320 | QFile file("testSetIoDevice.zip");
|
---|
321 | zip.setIoDevice(&file);
|
---|
322 | QCOMPARE(zip.getIoDevice(), &file);
|
---|
323 | zip.open(QuaZip::mdCreate);
|
---|
324 | QVERIFY(file.isOpen());
|
---|
325 | zip.close();
|
---|
326 | QVERIFY(!file.isOpen());
|
---|
327 | QVERIFY(file.exists());
|
---|
328 | QDir().remove(file.fileName());
|
---|
329 | }
|
---|
330 |
|
---|
331 | void TestQuaZip::setCommentCodec()
|
---|
332 | {
|
---|
333 | QuaZip zip("commentCodec.zip");
|
---|
334 | QVERIFY(zip.open(QuaZip::mdCreate));
|
---|
335 | zip.setCommentCodec("WINDOWS-1251");
|
---|
336 | zip.setComment(QString::fromUtf8("Вопрос"));
|
---|
337 | QuaZipFile zipFile(&zip);
|
---|
338 | QVERIFY(zipFile.open(QIODevice::WriteOnly, QuaZipNewInfo("test.txt")));
|
---|
339 | zipFile.close();
|
---|
340 | zip.close();
|
---|
341 | QVERIFY(zip.open(QuaZip::mdUnzip));
|
---|
342 | zip.setCommentCodec(QTextCodec::codecForName("KOI8-R"));
|
---|
343 | QCOMPARE(zip.getComment(), QString::fromUtf8("бНОПНЯ"));
|
---|
344 | zip.close();
|
---|
345 | QDir().remove(zip.getZipName());
|
---|
346 | }
|
---|
347 |
|
---|
348 | void TestQuaZip::setAutoClose()
|
---|
349 | {
|
---|
350 | {
|
---|
351 | QBuffer buf;
|
---|
352 | QuaZip zip(&buf);
|
---|
353 | QVERIFY(zip.isAutoClose());
|
---|
354 | QVERIFY(zip.open(QuaZip::mdCreate));
|
---|
355 | QVERIFY(buf.isOpen());
|
---|
356 | zip.close();
|
---|
357 | QVERIFY(!buf.isOpen());
|
---|
358 | QVERIFY(zip.open(QuaZip::mdCreate));
|
---|
359 | }
|
---|
360 | {
|
---|
361 | QBuffer buf;
|
---|
362 | QuaZip zip(&buf);
|
---|
363 | QVERIFY(zip.isAutoClose());
|
---|
364 | zip.setAutoClose(false);
|
---|
365 | QVERIFY(!zip.isAutoClose());
|
---|
366 | QVERIFY(zip.open(QuaZip::mdCreate));
|
---|
367 | QVERIFY(buf.isOpen());
|
---|
368 | zip.close();
|
---|
369 | QVERIFY(buf.isOpen());
|
---|
370 | QVERIFY(zip.open(QuaZip::mdCreate));
|
---|
371 | }
|
---|
372 | }
|
---|
373 |
|
---|
374 | #ifdef QUAZIP_TEST_QSAVEFILE
|
---|
375 | void TestQuaZip::saveFileBug()
|
---|
376 | {
|
---|
377 | QDir curDir;
|
---|
378 | QString zipName = "testSaveFile.zip";
|
---|
379 | if (curDir.exists(zipName)) {
|
---|
380 | if (!curDir.remove(zipName)) {
|
---|
381 | QFAIL("Can't remove testSaveFile.zip");
|
---|
382 | }
|
---|
383 | }
|
---|
384 | QuaZip zip;
|
---|
385 | QSaveFile saveFile(zipName);
|
---|
386 | zip.setIoDevice(&saveFile);
|
---|
387 | QCOMPARE(zip.getIoDevice(), &saveFile);
|
---|
388 | zip.open(QuaZip::mdCreate);
|
---|
389 | zip.close();
|
---|
390 | QVERIFY(QFileInfo(saveFile.fileName()).exists());
|
---|
391 | curDir.remove(saveFile.fileName());
|
---|
392 | }
|
---|
393 | #endif
|
---|
394 |
|
---|
395 | void TestQuaZip::testSequential()
|
---|
396 | {
|
---|
397 | QTcpServer server;
|
---|
398 | QVERIFY(server.listen(QHostAddress(QHostAddress::LocalHost)));
|
---|
399 | quint16 port = server.serverPort();
|
---|
400 | QTcpSocket socket;
|
---|
401 | socket.connectToHost(QHostAddress(QHostAddress::LocalHost), port);
|
---|
402 | QVERIFY(socket.waitForConnected());
|
---|
403 | QVERIFY(server.waitForNewConnection(30000));
|
---|
404 | QTcpSocket *client = server.nextPendingConnection();
|
---|
405 | QuaZip zip(&socket);
|
---|
406 | zip.setAutoClose(false);
|
---|
407 | QVERIFY(zip.open(QuaZip::mdCreate));
|
---|
408 | QVERIFY(socket.isOpen());
|
---|
409 | QuaZipFile zipFile(&zip);
|
---|
410 | QuaZipNewInfo info("test.txt");
|
---|
411 | QVERIFY(zipFile.open(QIODevice::WriteOnly, info, NULL, 0, 0));
|
---|
412 | QCOMPARE(zipFile.write("test"), static_cast<qint64>(4));
|
---|
413 | zipFile.close();
|
---|
414 | zip.close();
|
---|
415 | QVERIFY(socket.isOpen());
|
---|
416 | socket.disconnectFromHost();
|
---|
417 | QVERIFY(socket.waitForDisconnected());
|
---|
418 | QVERIFY(client->waitForReadyRead());
|
---|
419 | QByteArray received = client->readAll();
|
---|
420 | #ifdef QUAZIP_QZTEST_QUAZIP_DEBUG_SOCKET
|
---|
421 | QFile debug("testSequential.zip");
|
---|
422 | debug.open(QIODevice::WriteOnly);
|
---|
423 | debug.write(received);
|
---|
424 | debug.close();
|
---|
425 | #endif
|
---|
426 | client->close();
|
---|
427 | QBuffer buffer(&received);
|
---|
428 | QuaZip receivedZip(&buffer);
|
---|
429 | QVERIFY(receivedZip.open(QuaZip::mdUnzip));
|
---|
430 | QVERIFY(receivedZip.goToFirstFile());
|
---|
431 | QuaZipFileInfo64 receivedInfo;
|
---|
432 | QVERIFY(receivedZip.getCurrentFileInfo(&receivedInfo));
|
---|
433 | QCOMPARE(receivedInfo.name, QString::fromLatin1("test.txt"));
|
---|
434 | QCOMPARE(receivedInfo.uncompressedSize, static_cast<quint64>(4));
|
---|
435 | QuaZipFile receivedFile(&receivedZip);
|
---|
436 | QVERIFY(receivedFile.open(QIODevice::ReadOnly));
|
---|
437 | QByteArray receivedText = receivedFile.readAll();
|
---|
438 | QCOMPARE(receivedText, QByteArray("test"));
|
---|
439 | receivedFile.close();
|
---|
440 | receivedZip.close();
|
---|
441 | }
|
---|