
本文档介绍了如何在Java Structs框架中动态生成CSV文件,并将其上传到FTP服务器,而无需在本地磁盘上创建实际文件。通过使用ByteArrayOutputStream和ByteArrayInputStream,我们可以直接在内存中创建CSV数据流,然后将其传递给FTP上传方法,从而提高效率并避免不必要的磁盘操作。
在传统的Java Structs应用中,生成CSV文件并上传到FTP服务器通常涉及以下步骤:
- 在本地磁盘上创建一个临时CSV文件。
- 将数据写入该文件。
- 使用FTP客户端连接到FTP服务器。
- 将本地文件上传到FTP服务器。
- 删除本地临时文件。
这种方法存在一些缺点:需要在磁盘上创建临时文件,这可能会影响性能和安全性。此外,如果上传过程中出现错误,可能需要手动删除临时文件。
为了解决这些问题,我们可以使用ByteArrayOutputStream和ByteArrayInputStream来动态创建CSV文件,而无需在磁盘上创建实际文件。
立即学习“Java免费学习笔记(深入)”;
使用ByteArrayOutputStream和ByteArrayInputStream
ByteArrayOutputStream是一个字节数组输出流,它可以将数据写入到内存中的字节数组中。ByteArrayInputStream是一个字节数组输入流,它可以从内存中的字节数组中读取数据。
以下是使用ByteArrayOutputStream和ByteArrayInputStream动态创建CSV文件并上传到FTP服务器的示例代码:
import java.io.*;
public ActionForward generatePayroll(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
SessionInfoForm _form = (SessionInfoForm) form;
SisTransactionsSession _config = _form.getSisTransactionsSession();
String loggedInUser = _form.getLoggedinEmployeeDVO().getLoginId().toUpperCase();
String[] business = request.getParameterValues("selectedBusinessValues");
String[] position = request.getParameterValues("selectedPositionValues");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try (Writer writer = new OutputStreamWriter(bos)) {
writer.write(business.toString());
writer.write(position.toString());
} catch (IOException e) {
e.printStackTrace();
// 处理异常
return mapping.findForward("error"); // 或者其他错误处理方式
}
InputStream inputStream = new ByteArrayInputStream(bos.toByteArray());
// 调用FTP上传方法
boolean uploadSuccess = fileUpload(inputStream, "your_directory", loggedInUser, "PAYROLL_PRM.csv");
if (uploadSuccess) {
return mapping.findForward("success");
} else {
return mapping.findForward("error");
}
}
private boolean fileUpload(InputStream isUploadFile, String dirName, String loggedInUser, String fileName){
boolean storeRetVal = false;
String fileType = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());
storeRetVal = SISSFTPManager.getInstance().put(isUploadFile, dirName, fileName);
if (storeRetVal)
{
try {
if (fileType.trim().equalsIgnoreCase("csv")){
ICSAPI.getInstance().getSIMSOrderManager().createFileAudit(loggedInUser, fileName);
} else {
}
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SystemException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ApplicationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
logger.info("BulkUploadAction:fileUpload SFTP Transfer file successfully!");
} else {
logger.error("BulkUploadAction:fileUpload SFTP Transfer file FAILED!");
}
return storeRetVal;
}代码解释:
- 创建ByteArrayOutputStream: ByteArrayOutputStream bos = new ByteArrayOutputStream(); 创建一个新的字节数组输出流。
- 使用OutputStreamWriter写入数据: try (Writer writer = new OutputStreamWriter(bos)) { ... } 创建一个 OutputStreamWriter ,它将字符写入 ByteArrayOutputStream 。 使用 try-with-resources 语句确保 writer 在使用后被正确关闭。 writer.write(business.toString()); 和 writer.write(position.toString()); 将数据写入输出流。 注意: business 和 position 是字符串数组,直接调用 toString() 方法可能不会产生期望的CSV格式。 你需要根据CSV格式的要求,将数组中的元素进行格式化,例如使用逗号分隔。
- 创建ByteArrayInputStream: InputStream inputStream = new ByteArrayInputStream(bos.toByteArray()); 将 ByteArrayOutputStream 中的字节数组转换为 ByteArrayInputStream ,以便可以将其作为输入流传递给FTP上传方法。
- 调用FTP上传方法: fileUpload(inputStream, "your_directory", loggedInUser, "PAYROLL_PRM.csv"); 调用现有的 fileUpload 方法,将输入流、目录名、用户名和文件名传递给它。
- 异常处理: 在 try-catch 块中处理 IOException ,并在出现错误时返回错误转发。
注意事项:
- CSV格式化: 示例代码直接使用toString()方法将数组转换为字符串,这通常不是CSV的正确格式。你需要根据实际需求,使用循环或其他方法将数组元素格式化为CSV格式,例如使用逗号分隔每个字段。
- 字符编码: 在使用OutputStreamWriter时,需要注意字符编码。如果需要使用特定的字符编码,可以在创建OutputStreamWriter时指定,例如new OutputStreamWriter(bos, "UTF-8")。
- 异常处理: 在实际应用中,需要对可能出现的异常进行适当的处理,例如IOException、FTP连接错误等。
总结
使用ByteArrayOutputStream和ByteArrayInputStream可以在Java Structs中动态创建CSV文件,而无需在本地磁盘上创建实际文件。这种方法可以提高效率,避免不必要的磁盘操作,并简化代码。但是,需要注意CSV格式化、字符编码和异常处理等问题。










