我需要在5秒内创建100mb压缩文件,其中包含使用java的CSV文件。我创建了包含CSV文件的test.zip,但生成zip文件需要花费太多时间(约30秒)。这是我到目前为止编写的代码:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
/* Create instance of ZipOutputStream to create ZIP file. */
ZipOutputStream zipOutputStream = new ZipOutputStream(baos);
/* Create ZIP entry for file.The file which is created put into the
* zip file.File is not on the disk, csvFileName indicates only the
* file name to be put into the zip
*/
ZipEntry zipEntry = new ZipEntry("Test.zip");
zipOutputStream.putNextEntry(zipEntry);
/* Create OutputStreamWriter for CSV. There is no need for staging
* the CSV on filesystem . Directly write bytes to the output stream.
*/
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(zipOutputStream, "UTF-8"));
CsvListWriter csvListWriter = new CsvListWriter(bufferedWriter, CsvPreference.EXCEL_PREFERENCE);
/* Write the CSV header to the generated CSV file. */
csvListWriter.writeHeader(CSVGeneratorConstant.CSV_HEADERS);
/* Logic to Write the content to CSV */
long startTime = System.currentTimeMillis();
for (int rowIdx = 0; rowIdx < 7000000; rowIdx++) {
final List<String> rowContent = new LinkedList<String>();
for (int colIdx = 0; colIdx < 6; colIdx++) {
String str = "R" + rowIdx + "C" + colIdx + " FieldContent";
rowContent.add(str);
}
csvListWriter.write(rowContent);
}
long stopTime = System.currentTimeMillis();
long elapsedTime = stopTime - startTime;
System.out.println("time==" + elapsedTime / 1000f + "Seconds");
System.out.println("Size=====" + baos.size() / (Math.pow(1024, 2)) + "MB");
csvListWriter.close();
bufferedWriter.close();
zipOutputStream.close();
baos.close();
我正在使用超级csv库,但我也尝试在没有超级csv lib的内存中创建zip文件但没有成功。你能帮我吗?
答案 0 :(得分:0)
您的测试数据大约为1GB,压缩到100MB。根据您的硬件,可能无法实现&lt; 5s表现。
我已经整理了一个快速而肮脏的基准,突出了写入zip文件对性能的影响。
String.join()
:9.6s String.join()
:18.6s 使用Super CSV(~122%)似乎有一点点开销,但只需写入一个zip文件几乎可以加倍(~190%)时间,无论是否使用Super CSV使用。
这里是4个场景的代码。
与您提供的代码不同,我直接写入文件(我没有注意到写入磁盘与写入内存之间有任何区别,即ByteArrayOutputStream
)。我还跳过了Super CSV示例中的BufferedWriter
,因为它已经在内部使用了它,并且我已经使用了try-with-resources来使事情变得更清晰。
@Test
public void testWriteToCsvFileWithSuperCSV() throws Exception {
long startTime = System.currentTimeMillis();
try (FileOutputStream csvFile = new FileOutputStream(new File("supercsv.csv"));
ICsvListWriter writer = new CsvListWriter(new OutputStreamWriter(csvFile, "UTF-8"), CsvPreference.EXCEL_PREFERENCE)
){
for (int rowIdx = 0; rowIdx < 7000000; rowIdx++) {
final List<String> rowContent = new LinkedList<>();
for (int colIdx = 0; colIdx < 6; colIdx++) {
String str = "R" + rowIdx + "C" + colIdx + " FieldContent";
rowContent.add(str);
}
writer.write(rowContent);
}
}
long stopTime = System.currentTimeMillis();
long elapsedTime = stopTime - startTime;
System.out.println("Writing to CSV with Super CSV took " + (elapsedTime / 1000f) + " seconds");
}
@Test
public void testWriteToCsvFileWithinZipWithSuperCSV() throws Exception {
long startTime = System.currentTimeMillis();
try (FileOutputStream zipFile = new FileOutputStream(new File("supercsv.zip"));
ZipOutputStream zos = new ZipOutputStream(zipFile);
ICsvListWriter writer = new CsvListWriter(new OutputStreamWriter(zos, "UTF-8"), CsvPreference.EXCEL_PREFERENCE)
){
ZipEntry csvFile = new ZipEntry("supercsvwithinzip.csv");
zos.putNextEntry(csvFile);
for (int rowIdx = 0; rowIdx < 7000000; rowIdx++) {
final List<String> rowContent = new LinkedList<>();
for (int colIdx = 0; colIdx < 6; colIdx++) {
String str = "R" + rowIdx + "C" + colIdx + " FieldContent";
rowContent.add(str);
}
writer.write(rowContent);
}
}
long stopTime = System.currentTimeMillis();
long elapsedTime = stopTime - startTime;
System.out.println("Writing to CSV within zip file with Super CSV took " + (elapsedTime / 1000f) + " seconds");
}
@Test
public void testWriteToCsvFileWithStringJoin() throws Exception {
long startTime = System.currentTimeMillis();
try (FileOutputStream textFile = new FileOutputStream(new File("join.csv"));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(textFile, "UTF-8"));
){
for (int rowIdx = 0; rowIdx < 7000000; rowIdx++) {
final List<String> rowContent = new LinkedList<>();
for (int colIdx = 0; colIdx < 6; colIdx++) {
String str = "R" + rowIdx + "C" + colIdx + " FieldContent";
rowContent.add(str);
}
writer.append(String.join(",", rowContent) + "\n");
}
}
long stopTime = System.currentTimeMillis();
long elapsedTime = stopTime - startTime;
System.out.println("Writing to CSV with String.join() took " + (elapsedTime / 1000f) + " seconds");
}
@Test
public void testWriteToCsvFileWithinZipWithStringJoin() throws Exception {
long startTime = System.currentTimeMillis();
try (FileOutputStream zipFile = new FileOutputStream(new File("join.zip"));
ZipOutputStream zos = new ZipOutputStream(zipFile);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(zos, "UTF-8"));
){
ZipEntry csvFile = new ZipEntry("joinwithinzip.csv");
zos.putNextEntry(csvFile);
for (int rowIdx = 0; rowIdx < 7000000; rowIdx++) {
final List<String> rowContent = new LinkedList<>();
for (int colIdx = 0; colIdx < 6; colIdx++) {
String str = "R" + rowIdx + "C" + colIdx + " FieldContent";
rowContent.add(str);
}
writer.append(String.join(",", rowContent) + "\n");
}
}
long stopTime = System.currentTimeMillis();
long elapsedTime = stopTime - startTime;
System.out.println("Writing to CSV within zip with String.join() took " + (elapsedTime / 1000f) + " seconds");
}