java.lang.IllegalStateException: getWriter() has already been called for this response
在执行下述代码时报错,
OutputStream out = getResponse().getOutputStream();
原因为代码中有打开的Response.getWriter(),未关闭,因调用点较多,不好一一排查。
通过查看代码,看到response中的usingWriter=true,随即想办法将该标志位设置为false。
response.reset(); 即可,注意reset后缓存消失,设置消失。
OutputStream和Writer在一个response中不能同时获得。
具体内容见:
public static void filedownShowEX(String fileName, String filePath,HttpServletRequest request, HttpServletResponse response)
throws Exception {}
方法如下:
package com.fh.util;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 文件处理 创建人:BYL 创建时间:2014年12月23日
*/
public class FileUtils {
public static void filedown(String fileName, String filePath,
HttpServletRequest request, HttpServletResponse response) {
try {
// 得到该文件
File file = new File(filePath + fileName);
if (!file.exists()) {
System.out.println("Have no such file!");
return;// 文件不存在就退出方法
}
FileInputStream fileInputStream = new FileInputStream(file);
// 设置Http响应头告诉浏览器下载这个附件
String userAgent = request.getHeader("User-Agent");
// 针对IE或者以IE为内核的浏览器:
if (userAgent.contains("MSIE") || userAgent.contains("Trident")) {
fileName = java.net.URLEncoder.encode(fileName, "UTF-8");
} else {
// 非IE浏览器的处理:
fileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
}
response.setHeader("Content-disposition",
String.format("attachment; filename=\"%s\"", fileName));
response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.setCharacterEncoding("UTF-8");
OutputStream outputStream = response.getOutputStream();
byte[] bytes = new byte[2048];
int len = 0;
while ((len = fileInputStream.read(bytes)) > 0) {
outputStream.write(bytes, 0, len);
}
fileInputStream.close();
outputStream.close();
} catch (Exception e) {
// TODO: handle exception
}
}
/**
* 文件下载方法
* @param fileName 文件名称(PZ_DEMO.zip)
* @param filePath 文件路径(D://uploadFiles//PG//IMAGE//176d10329c29420e97fce1a39586a7b220190801091805//YX_zip_20190801091845856.zip)
* @param request
* @param response
*/
public static void filedownShowEX(String fileName, String filePath,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
// 看到response中的usingWriter=true,随即想办法将该标志位设置为false;response.reset(),即可,注意reset后缓存消失,设置消失。
response.reset();
// 得到该文件
File file = new File(filePath);
FileInputStream fileInputStream = new FileInputStream(file);
// 设置Http响应头告诉浏览器下载这个附件
String userAgent = request.getHeader("User-Agent");
// 针对IE或者以IE为内核的浏览器:
if (userAgent.contains("MSIE") || userAgent.contains("Trident")) {
fileName = java.net.URLEncoder.encode(fileName, "UTF-8");
} else {
// 非IE浏览器的处理:
fileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
}
response.setHeader("Content-disposition",
String.format("attachment; filename=\"%s\"", fileName));
response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.setCharacterEncoding("UTF-8");
OutputStream outputStream = response.getOutputStream();
byte[] bytes = new byte[2048];
int len = 0;
while ((len = fileInputStream.read(bytes)) > 0) {
outputStream.write(bytes, 0, len);
}
fileInputStream.close();
outputStream.close();
}
/**
* txt文件编码判断
*
* @param filePath
* 文件路径
* @return (是:true(是:US-ASCII 编码) ;否:false(不是:US-ASCII 编码) )
* @throws Exception
*/
// java编码 与 txt编码对应
// java txt
// unicode unicode big endian
// utf-8 utf-8
// utf-16 unicode
// gb2312 ANSI
public static boolean checkIsFileASCII(String filepath) throws Exception {
File sourceFile = new File(filepath);
String charset = "GB2312";
byte[] first3Bytes = new byte[3];
try {
boolean checked = false;
BufferedInputStream bis = new BufferedInputStream(
new FileInputStream(sourceFile));
bis.mark(0);
int read = bis.read(first3Bytes, 0, 3);
if (read == -1) {
charset = "GB2312"; // 文件编码为 ANSI
} else if (first3Bytes[0] == (byte) 0xFF
&& first3Bytes[1] == (byte) 0xFE) {
charset = "UTF-16LE"; // 文件编码为 Unicode
checked = true;
} else if (first3Bytes[0] == (byte) 0xFE
&& first3Bytes[1] == (byte) 0xFF) {
charset = "UTF-16BE"; // 文件编码为 Unicode big endian
checked = true;
} else if (first3Bytes[0] == (byte) 0xEF
&& first3Bytes[1] == (byte) 0xBB
&& first3Bytes[2] == (byte) 0xBF) {
charset = "UTF-8"; // 文件编码为 UTF-8
checked = true;
}
bis.reset();
if (!checked) {
int loc = 0;
while ((read = bis.read()) != -1) {
loc++;
if (read >= 0xF0)
break;
if (0x80 <= read && read <= 0xBF) // 单独出现BF以下的,也算是GBK
break;
if (0xC0 <= read && read <= 0xDF) {
read = bis.read();
if (0x80 <= read && read <= 0xBF) // 双字节 (0xC0 - 0xDF)
// (0x80
// - 0xBF),也可能在GB编码内
continue;
else
break;
} else if (0xE0 <= read && read <= 0xEF) {// 也有可能出错,但是几率较小
read = bis.read();
if (0x80 <= read && read <= 0xBF) {
read = bis.read();
if (0x80 <= read && read <= 0xBF) {
charset = "UTF-8";
break;
} else
break;
} else
break;
}
}
}
bis.close();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("文件:" + filepath + "的编码格式为:" + charset);
if (charset.equalsIgnoreCase("GB2312")) {
return true;
} else {
return false;
}
}
/**
* 创建目录
*
* @param destDirName目标目录名
* @return
*/
public static Boolean createDir(String destDirName) {
File dir = new File(destDirName);
if (!dir.getParentFile().exists()) { // 判断有没有父路径,就是判断文件整个路径是否存在
return dir.getParentFile().mkdirs(); // 不存在就全部创建
}
return false;
}
/**
* 删除文件
*
* @param filePathAndName
* String 文件路径及名称 如c:/fqf.txt
* @param fileContent
* String
* @return boolean
*/
public static void delFile(String filePathAndName) {
try {
String filePath = filePathAndName;
filePath = filePath.toString();
java.io.File myDelFile = new java.io.File(filePath);
myDelFile.delete();
} catch (Exception e) {
System.out.println("删除文件操作出错");
e.printStackTrace();
}
}
/**
* 读取到字节数组0
*
* @param filePath
* //路径
* @throws IOException
*/
public static byte[] getContent(String filePath) throws IOException {
File file = new File(filePath);
long fileSize = file.length();
if (fileSize > Integer.MAX_VALUE) {
System.out.println("file too big...");
return null;
}
FileInputStream fi = new FileInputStream(file);
byte[] buffer = new byte[(int) fileSize];
int offset = 0;
int numRead = 0;
while (offset < buffer.length
&& (numRead = fi.read(buffer, offset, buffer.length - offset)) >= 0) {
offset += numRead;
}
// 确保所有数据均被读取
if (offset != buffer.length) {
throw new IOException("Could not completely read file "
+ file.getName());
}
fi.close();
return buffer;
}
/**
* 读取到字节数组1
*
* @param filePath
* @return
* @throws IOException
*/
public static byte[] toByteArray(String filePath) throws IOException {
File f = new File(filePath);
if (!f.exists()) {
throw new FileNotFoundException(filePath);
}
ByteArrayOutputStream bos = new ByteArrayOutputStream((int) f.length());
BufferedInputStream in = null;
try {
in = new BufferedInputStream(new FileInputStream(f));
int buf_size = 1024;
byte[] buffer = new byte[buf_size];
int len = 0;
while (-1 != (len = in.read(buffer, 0, buf_size))) {
bos.write(buffer, 0, len);
}
return bos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
throw e;
} finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
bos.close();
}
}
/**
* 读取到字节数组2
*
* @param filePath
* @return
* @throws IOException
*/
public static byte[] toByteArray2(String filePath) throws IOException {
File f = new File(filePath);
if (!f.exists()) {
throw new FileNotFoundException(filePath);
}
FileChannel channel = null;
FileInputStream fs = null;
try {
fs = new FileInputStream(f);
channel = fs.getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate((int) channel.size());
while ((channel.read(byteBuffer)) > 0) {
// do nothing
// System.out.println("reading");
}
return byteBuffer.array();
} catch (IOException e) {
e.printStackTrace();
throw e;
} finally {
try {
channel.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
fs.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* Mapped File way MappedByteBuffer 可以在处理大文件时,提升性能
*
* @param filename
* @return
* @throws IOException
*/
public static byte[] toByteArray3(String filePath) throws IOException {
FileChannel fc = null;
RandomAccessFile rf = null;
try {
rf = new RandomAccessFile(filePath, "r");
fc = rf.getChannel();
MappedByteBuffer byteBuffer = fc.map(MapMode.READ_ONLY, 0,
fc.size()).load();
// System.out.println(byteBuffer.isLoaded());
byte[] result = new byte[(int) fc.size()];
if (byteBuffer.remaining() > 0) {
// System.out.println("remain");
byteBuffer.get(result, 0, byteBuffer.remaining());
}
return result;
} catch (IOException e) {
e.printStackTrace();
throw e;
} finally {
try {
rf.close();
fc.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 写入文件
*
* @param filePath
* @param content
*/
public static void contentToTxt(String filePath, String content) {
String str = new String(); // 原有txt内容
String s1 = new String();// 内容更新
try {
File f = new File(filePath);
if (f.exists()) {
System.out.print("文件内容写入时 文件存在");
BufferedWriter output = new BufferedWriter(new FileWriter(f));
output.write("");
output.close();
} else {
System.out.print("文件内容写入时 文件不存在");
f.createNewFile();// 不存在则创建
}
BufferedWriter output = new BufferedWriter(new FileWriter(f));
output.write(content);
output.close();
} catch (Exception e) {
e.printStackTrace();
}
}
// 读取文件总行数
public static int readFileLineNums(String filepath, String filename) {
int x = 0;// 用于统计行数,从0开始
try {
FileReader fr = new FileReader(filepath); // 这里定义一个字符流的输入流的节点流,用于读取文件(一个字符一个字符的读取)
BufferedReader br = new BufferedReader(fr); // 在定义好的流基础上套接一个处理流,用于更加效率的读取文件(一行一行的读取)
while (br.readLine() != null) { // readLine()方法是按行读的,返回值是这行的内容
x++; // 每读一行,则变量x累加1
}
br.close();
fr.close();
} catch (Exception e) {
e.printStackTrace();
}
return x; // 返回总的行数
}
}