创建 CSV 文件而不将其保存到文件系统中
Create CSV file without saving it into file system
我创建了一个 Java 程序来创建一个 csv
文件,将数据写入其中,然后将其内容发送到服务器。
在本地,一切正常。但问题是我对服务器没有写权限(权限被拒绝的问题)。
所以,我什么也做不了chmod 777
。
我正在寻找一种创建 csv
文件而不保存到文件系统的方法。类似于写入流或流的东西。我真的不知道它是如何工作的。
有什么帮助吗?
这是我到目前为止所做的:
public void exportAllToCSV(@PathVariable int id,HttpServletResponse response) throws IOException
String csvFile="test.csv";
File file = new File("test.csv");
//some treatments to get datas (headers and values)
FileWriter writer = new FileWriter(csvFile);
CsvBuilder.writeLine(writer, headers);
CsvBuilder.writeLine(writer, values);
writer.flush();
writer.close();
response.setContentType("text/csv");
response.setHeader("Content-Disposition", "attachment; filename=" + csvFile);
final BufferedReader br = new BufferedReader(new FileReader(file));
try {
String line;
while ((line = br.readLine()) != null) {
response.getWriter().write(line + "\n");
}
} finally {
br.close();
}
try {
file.delete(); // I delete the file
} catch (Exception e) {
e.printStackTrace();
}
你可以试试,如果允许临时文件:
File temp = File.createTempFile("test.csv", ".csv");
这些文件是在系统的用户存储中创建的,例如 Windows 中的 "C:\Users[Username]\AppData" 或类似的东西。我不知道确切的路径,但现在应该不重要了。
查看 Java 中存在的所有类型的 OutputStreams,比 FileOutputStream 还多:
https://docs.oracle.com/javase/7/docs/api/java/io/OutputStream.html
检查子类。
您可以尝试直接写回复:
Writer writer = response.getWriter();
CsvBuilder.writeLine(writer, headers);
CsvBuilder.writeLine(writer, values);
writer.flush();
writer.close();
response.setContentType("text/csv");
response.setHeader("Content-Disposition","attachment; filename=" + csvFile);
如果由于某种原因不能使用并且临时文件也不允许你使用,你可以尝试使用这个非常丑陋的 in-memory 变体。
List<Integer> output = new LinkedList<>();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new OutputStream() {
@Override
public void write(int b) throws IOException {
output.add(b);
}
}));
// write all the things via CsvBuilder
final BufferedReader reader = new BufferedReader(new InputStreamReader(new InputStream() {
@Override
public int read() throws IOException {
if (output.size() > 0) {
return output.remove(0);
}
return -1;
}
}));
假设 CsvBuilder.writeLine(...)
只接受 java.io.Writer
的实例,为什么不使用 java.io.StringWriter
和 java.util.Scanner
?
// ...
StringWriter writer = new StringWriter();
CsvBuilder.writeLine(writer, headers);
CsvBuilder.writeLine(writer, values);
writer.flush();
response.setContentType("text/csv");
response.setHeader("Content-Disposition", "attachment; filename=test.csv");
Scanner scanner = new Scanner(new StringReader(writer.toString()));
while (scanner.hasNext()) {
response.getWriter().write(scanner.next() + "\n");
}
// ...
但是,我认为 Andrei Makarevich 直接使用 response.getWriter()
的回答可能是最先进的方法。虽然,我不确定 CsvBuilder
是否会添加换行符,因为你明确地添加了它们!?
您可以使用 StringBuilderWriter 代替 FileWriter 来编写程序
final Writer writer = new StringBuilderWriter();
万一有人还在寻找答案,下面的代码对我来说非常有用
导入以下依赖项
<dependency>
<groupId>net.sourceforge.javacsv</groupId>
<artifactId>javacsv</artifactId>
<version>2.0</version>
</dependency>
下面的代码,我正在将数据写入 ByteArrayOutputStream,而不是 FileWriter
ByteArrayOutputStream out = new ByteArrayOutputStream();
CsvWriter csvWriter = new CsvWriter(new BufferedOutputStream(out), ',', Charset.forName("UTF-8"));
String[] data = new String[] { "fieldValueA", "fieldValueB", "fieldValueC" };
csvWriter.writeRecord(data);
csvWriter.close();
我创建了一个 Java 程序来创建一个 csv
文件,将数据写入其中,然后将其内容发送到服务器。
在本地,一切正常。但问题是我对服务器没有写权限(权限被拒绝的问题)。
所以,我什么也做不了chmod 777
。
我正在寻找一种创建 csv
文件而不保存到文件系统的方法。类似于写入流或流的东西。我真的不知道它是如何工作的。
有什么帮助吗?
这是我到目前为止所做的:
public void exportAllToCSV(@PathVariable int id,HttpServletResponse response) throws IOException
String csvFile="test.csv";
File file = new File("test.csv");
//some treatments to get datas (headers and values)
FileWriter writer = new FileWriter(csvFile);
CsvBuilder.writeLine(writer, headers);
CsvBuilder.writeLine(writer, values);
writer.flush();
writer.close();
response.setContentType("text/csv");
response.setHeader("Content-Disposition", "attachment; filename=" + csvFile);
final BufferedReader br = new BufferedReader(new FileReader(file));
try {
String line;
while ((line = br.readLine()) != null) {
response.getWriter().write(line + "\n");
}
} finally {
br.close();
}
try {
file.delete(); // I delete the file
} catch (Exception e) {
e.printStackTrace();
}
你可以试试,如果允许临时文件:
File temp = File.createTempFile("test.csv", ".csv");
这些文件是在系统的用户存储中创建的,例如 Windows 中的 "C:\Users[Username]\AppData" 或类似的东西。我不知道确切的路径,但现在应该不重要了。
查看 Java 中存在的所有类型的 OutputStreams,比 FileOutputStream 还多: https://docs.oracle.com/javase/7/docs/api/java/io/OutputStream.html 检查子类。
您可以尝试直接写回复:
Writer writer = response.getWriter();
CsvBuilder.writeLine(writer, headers);
CsvBuilder.writeLine(writer, values);
writer.flush();
writer.close();
response.setContentType("text/csv");
response.setHeader("Content-Disposition","attachment; filename=" + csvFile);
如果由于某种原因不能使用并且临时文件也不允许你使用,你可以尝试使用这个非常丑陋的 in-memory 变体。
List<Integer> output = new LinkedList<>();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new OutputStream() {
@Override
public void write(int b) throws IOException {
output.add(b);
}
}));
// write all the things via CsvBuilder
final BufferedReader reader = new BufferedReader(new InputStreamReader(new InputStream() {
@Override
public int read() throws IOException {
if (output.size() > 0) {
return output.remove(0);
}
return -1;
}
}));
假设 CsvBuilder.writeLine(...)
只接受 java.io.Writer
的实例,为什么不使用 java.io.StringWriter
和 java.util.Scanner
?
// ...
StringWriter writer = new StringWriter();
CsvBuilder.writeLine(writer, headers);
CsvBuilder.writeLine(writer, values);
writer.flush();
response.setContentType("text/csv");
response.setHeader("Content-Disposition", "attachment; filename=test.csv");
Scanner scanner = new Scanner(new StringReader(writer.toString()));
while (scanner.hasNext()) {
response.getWriter().write(scanner.next() + "\n");
}
// ...
但是,我认为 Andrei Makarevich 直接使用 response.getWriter()
的回答可能是最先进的方法。虽然,我不确定 CsvBuilder
是否会添加换行符,因为你明确地添加了它们!?
您可以使用 StringBuilderWriter 代替 FileWriter 来编写程序
final Writer writer = new StringBuilderWriter();
万一有人还在寻找答案,下面的代码对我来说非常有用
导入以下依赖项
<dependency>
<groupId>net.sourceforge.javacsv</groupId>
<artifactId>javacsv</artifactId>
<version>2.0</version>
</dependency>
下面的代码,我正在将数据写入 ByteArrayOutputStream,而不是 FileWriter
ByteArrayOutputStream out = new ByteArrayOutputStream();
CsvWriter csvWriter = new CsvWriter(new BufferedOutputStream(out), ',', Charset.forName("UTF-8"));
String[] data = new String[] { "fieldValueA", "fieldValueB", "fieldValueC" };
csvWriter.writeRecord(data);
csvWriter.close();