我正在尝试将3个不同表中的3个CSV文件压缩到单个zip文件your_files_12354627.zip
中。
因此,我采用以下方法,该方法对于其中包含1个csv文件的zip文件生成效果很好。我正在尝试对多个文件执行此操作,因此我修改了以下代码(如下工作代码所示):
下面的工作代码:
public void sendMessage(String msg) throws DaoException {
DataSource ds = null;
Connection conn = null;
PreparedStatement pstmt = null;
PreparedStatement pstmtEmployee = null;
PreparedStatement pstmtCompany = null;
PreparedStatement pstmBuilding = null;
ResultSet rs = null;
ResultSet resultSetFirst = null;
ResultSet resultSetSecond = null;
ResultSet resultSetThird = null;
String[] parts = msg.split("#");
String requestID = parts[0].trim();
String userName = parts[1].trim();
String applicationName = parts[2].trim();
try {
ds = jdbcTemplate.getDataSource();
conn = ds.getConnection();
pstmtEmployee = conn.prepareStatement(getPatientEmployeeSQL);
pstmtEmployee.setString(1, requestID);
resultSetFirst = pstmtEmployee.executeQuery();
pstmtCompany = conn.prepareStatement(getCompanySQL);
pstmtCompany.setString(1, requestID);
resultSetSecond = pstmtCompany.executeQuery();
pstmtBuilding = conn.prepareStatement(getBuildingSQL);
pstmtBuilding.setString(1, requestID);
resultSetThird = pstmtBuilding.executeQuery();
Path dir = Paths.get("/srv/custom_users", userName);
Files.createDirectories(dir);
OutputStream fos = Files.newOutputStream(dir.resolve("your_files_"+ unixTimestamp +".zip"));
BufferedOutputStream bos = new BufferedOutputStream(fos);
ZipOutputStream zos = new ZipOutputStream(bos);
Path employeeFile = dir.resolve("employee_custom_file_" + unixTimestamp + ".csv");
Path companyFile = dir.resolve("company_custom_file_" + unixTimestamp + ".csv");
Path buildingFile = dir.resolve("building_custom_file_" + unixTimestamp + ".csv");
ZipEntry firstEntry = new ZipEntry(employeeFile.getFileName().toString());
zos.putNextEntry(firstEntry);
try (CSVWriter writer = new CSVWriter(new OutputStreamWriter(zos,StandardCharsets.UTF_8)))) {
writer.writeAll(resultSetFirst, true);
writer.flush();
zos.closeEntry();
}
/*ZipEntry secondEntry = new ZipEntry(companyFile.getFileName().toString());
zos.putNextEntry(secondEntry);
try (CSVWriter writer = new CSVWriter(new OutputStreamWriter(zos,StandardCharsets.UTF_8)))) {
writer.writeAll(resultSetSecond, true);
writer.flush();
zos.closeEntry();
}
ZipEntry thirdEntry = new ZipEntry(buildingFile.getFileName().toString());
zos.putNextEntry(thirdEntry);
try (CSVWriter writer = new CSVWriter(new OutputStreamWriter(zos,StandardCharsets.UTF_8)))) {
writer.writeAll(resultSetThird, true);
writer.flush();
zos.closeEntry();
}*/
zos.close();
}
catch(Throwable th) {
throw new DaoException(th.getMessage(), th);
}
finally {
//resource Closing statements
}
}
以下修改的代码:
我应该如何遍历3个不同的结果集,以便分别使用writer.writeAll(resultSetFirst, true);
,writer.writeAll(resultSetSecond, true);
和writer.writeAll(resultSetThird, true);
?我试图遍历下面代码中所示的文件名,但是不确定如何在for循环内处理不同的结果集,如下所示。我已经在试图找出此循环问题的位置发表了评论。
public void sendMessage(String msg) throws DaoException {
DataSource ds = null;
Connection conn = null;
PreparedStatement pstmt = null;
PreparedStatement pstmtEmployee = null;
PreparedStatement pstmtCompany = null;
PreparedStatement pstmBuilding = null;
ResultSet rs = null;
ResultSet resultSetFirst = null;
ResultSet resultSetSecond = null;
ResultSet resultSetThird = null;
String[] parts = msg.split("#");
String requestID = parts[0].trim();
String userName = parts[1].trim();
String applicationName = parts[2].trim();
try {
ds = jdbcTemplate.getDataSource();
conn = ds.getConnection();
pstmtEmployee = conn.prepareStatement(getPatientEmployeeSQL);
pstmtEmployee.setString(1, requestID);
resultSetFirst = pstmtEmployee.executeQuery();
pstmtCompany = conn.prepareStatement(getCompanySQL);
pstmtCompany.setString(1, requestID);
resultSetSecond = pstmtCompany.executeQuery();
pstmtBuilding = conn.prepareStatement(getBuildingSQL);
pstmtBuilding.setString(1, requestID);
resultSetThird = pstmtBuilding.executeQuery();
Path dir = Paths.get("/srv/custom_users", userName);
Files.createDirectories(dir);
OutputStream fos = Files.newOutputStream(dir.resolve("your_files_"+ unixTimestamp +".zip"));
BufferedOutputStream bos = new BufferedOutputStream(fos);
ZipOutputStream zos = new ZipOutputStream(bos);
Path employeeFile = dir.resolve("employee_custom_file_" + unixTimestamp + ".csv");
Path companyFile = dir.resolve("company_custom_file_" + unixTimestamp + ".csv");
Path buildingFile = dir.resolve("building_custom_file_" + unixTimestamp + ".csv");
List<String> csvFileNames = new ArrayList<String>();
csvFileNames.add(employeeFile.getFileName().toString());
csvFileNames.add(companyFile.getFileName().toString());
csvFileNames.add(buildingFile.getFileName().toString());
for (String entries : csvFileNames) {
ZipEntry entry = new ZipEntry(entries);
zos.putNextEntry(entry);
CSVWriter writer = new CSVWriter(new OutputStreamWriter(zos,StandardCharsets.UTF_8));
//How should I loop through different resultsets here so that I can make use of writer.writeAll(resultSetFirst, true);
// writer.writeAll(resultSetSecond, true); and writer.writeAll(resultSetThird, true); respectively?
System.out.println("Printing entries");
System.out.println(entries);
}
/*ZipEntry firstEntry = new ZipEntry(employeeFile.getFileName().toString());
zos.putNextEntry(firstEntry);
try (CSVWriter writer = new CSVWriter(new OutputStreamWriter(zos,StandardCharsets.UTF_8)))) {
writer.writeAll(resultSetFirst, true);
writer.flush();
zos.closeEntry();
}*/
/*ZipEntry secondEntry = new ZipEntry(companyFile.getFileName().toString());
zos.putNextEntry(secondEntry);
try (CSVWriter writer = new CSVWriter(new OutputStreamWriter(zos,StandardCharsets.UTF_8)))) {
writer.writeAll(resultSetSecond, true);
writer.flush();
zos.closeEntry();
}
ZipEntry thirdEntry = new ZipEntry(buildingFile.getFileName().toString());
zos.putNextEntry(thirdEntry);
try (CSVWriter writer = new CSVWriter(new OutputStreamWriter(zos,StandardCharsets.UTF_8)))) {
writer.writeAll(resultSetThird, true);
writer.flush();
zos.closeEntry();
}*/
zos.close();
}
catch(Throwable th) {
throw new DaoException(th.getMessage(), th);
}
finally {
//resource Closing statements
}
}
答案 0 :(得分:2)
首先,我建议您将代码分解为几种不同的方法。这里有很多重复。
对于您是要为每个文件编写一个ResultSet还是为每个文件编写三个ResultSet,我有些困惑。其中一部分是文件file
,fileFacts
和fileEncounters
,在其他任何地方都没有提及。
如果要在每个条目中放置一个ResultSet,则可以使用Map将File映射到ResultSet,然后遍历Entries或Key。像......
....
Map<String,ResultSet> dataMap = new HashMap<>();
dataMap.put(file.getFileName().toString(),resultSetFirst);
dataMap.put(filefacts.getFileName().toString(),resultSetSecond);
dataMap.put(fileEncounters.getFileName().toString(),resultSetThird);
for (Map.Entry<String,ResultSet> e : dataMap.entrySet()){
zos.putNextEntry(new ZipEntry(e.getKey()));
try (CSVWriter writer = new CSVWriter(new OutputStreamWriter(zos,StandardCharsets.UTF_8))){
writer.writeAll(e.getValue(), true);
writer.flush();
zos.closeEntry();
}
}
....
但是使用一种方法可能会更容易,更清晰...
....
makeEntry(zos,file.getFileName().toString(),resultSetFirst);
makeEntry(zos,filefacts.getFileName().toString(),resultSetSecond);
makeEntry(zos,fileEncounters.getFileName().toString(),resultSetThird);
....
}
private static void makeEntry(ZipOutputStream zos,String name, ResultSet res) throws SomeExceptions{
zos.putNextEntry(new ZipEntry(name));
try (CSVWriter writer = new CSVWriter(new OutputStreamWriter(zos,StandardCharsets.UTF_8))){
writer.writeAll(res, true);
writer.flush();
zos.closeEntry();
}
}
通过这种方法,您不必创建和填充地图(或列表)即可运行3次相同的代码。
如果您决定迭代地图以使内容更清晰/更干净,则可以/应该仍然使用一种方法:
Map<String,ResultSet> dataMap = new HashMap<>();
dataMap.put(file.getFileName().toString(),resultSetFirst);
dataMap.put(filefacts.getFileName().toString(),resultSetSecond);
dataMap.put(fileEncounters.getFileName().toString(),resultSetThird);
for (Map.Entry<String,ResultSet> e : dataMap.entrySet()){
makeEntry(zos, e.getKey(), e.getValue());
}
...
寻找这样的其他领域来重构方法。一个不错的规则是,每当您认为应该剪切和粘贴代码时,就考虑创建一个方法。
请注意,实际上这些代码都没有被编译或运行