
参考链接: https://codingdict.com/questions/112066
问题:使用Java读取文件或流的最可靠方法(以防止DoS攻击),限制文件大小
private static final int MAX_FILE_SIZE = 30 * 3;
private static final int MAX_CONTENT_LENGTH = 30;
测试方法:
** BoundedInputStream 不抛出异常**
@Test
public void testFile() {
// 步骤一: 写入字符串
String writeData = "FileUtils 牛皮 FileUtils 牛皮 FileUtils 牛皮";
try {
FileUtils.writeStringToFile(new File(fileName), writeData, StandardCharsets.UTF_8, false);
System.out.println("写入成功,字符串长度为: " + writeData.length());
} catch (IOException e) {
e.printStackTrace();
}
// 步骤二: 读取字符串
try {
InputStream inputStream = new FileInputStream(fileName);
// 规定读取的内容大小为MAX_CONTENT_LENGTH, 文件的内容大小为MAX_FILE_SIZE: BoundedInputStream 不抛出异常
String content = getContentFromInputStream(inputStream, MAX_FILE_SIZE, MAX_CONTENT_LENGTH);
System.out.println("读取的内容为:" + content);
} catch (Exception e) {
System.out.println("has an error");
}
}
getContentFromInputStream方法
public static String getContentFromInputStream(InputStream inputStream, int maxFileSize, int maxContentLength) {
// 超长, 不换行
BoundedInputStream boundedInput = new BoundedInputStream(inputStream, maxFileSize);
// todo: StringBuilder变量的资源耗尽(当文件包含的数据大于可用内存时)
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(boundedInput));
String lineSeparator = System.getProperty("line.separator");
String fileLine;
boolean firstLine = true;
try {
// todo: BufferedReader.readLine 容易受到DOS(拒绝服务)攻击(无限长的行,没有换行/回车的巨大文件)
fileLine = bufferedReader.readLine();
while (fileLine != null) {
// 不是第一行,添加分隔符
if (!firstLine) {
stringBuilder.append(lineSeparator);
}
if (stringBuilder.length() + fileLine.length() > maxContentLength) {
throw new IOException("content is too long");
}
stringBuilder.append(fileLine);
fileLine = bufferedReader.readLine();
firstLine = false;
}
} catch (IOException e) {
//TODO : throw or handle the exception
e.printStackTrace();
}
//TODO : close the stream
return stringBuilder.toString();
}