try {
//spring,springBoot环境下可以使用此方式,也可以直接new File(path)
File keyWordFile = ResourceUtils.getFile("classpath:keyWord.txt");
BufferedReader reader = new BufferedReader(new FileReader(keyWordFile));
//使用StringBuilder更快,但不安全,因为此处只有读,所以不影响
StringBuilder buffer = new StringBuilder();
String keyWord = null;
while ((keyWord = reader.readLine()) != null) {
buffer.append(keyWord);
}
//去除字符串中的空格
String keyWords = buffer.toString().replaceAll("\\s*", "");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
方式二:使用IOUtils
String s = IOUtils.toString(new FileInputStream(keyWordFile) , "UTF-8");
//去除空格和换行符
String keyWords = keyWordStr.replaceAll("\\s*", "").replaceAll("\\n","");
以上两种方式从编码简洁度来讲,肯定是第二种好很多,但其实性能是差不多的,一个是牺牲了读的性能,另一个是牺牲了写的性能。
两种结果的区别:使用BufferedReader是一行一行的读取,随后使用StringBuilder添加,所以是没有换行符的,而IOUtils是直接将整个文件的内容转成了字符串,所以也包括了换行符。
我们来看一下IOUtils的底层实现原理:
public static String toString(InputStream input, Charset encoding) throws IOException {
StringBuilderWriter sw = new StringBuilderWriter();
copy((InputStream)input, (Writer)sw, (Charset)encoding);
return sw.toString();
}
public static void copy(InputStream input, Writer output, Charset inputEncoding) throws IOException {
InputStreamReader in = new InputStreamReader(input, Charsets.toCharset(inputEncoding));
copy((Reader)in, (Writer)output);
}
public static int copy(Reader input, Writer output) throws IOException {
long count = copyLarge(input, output);
return count > 2147483647L ? -1 : (int)count;
}
public static long copyLarge(Reader input, Writer output) throws IOException {
return copyLarge(input, output, new char[4096]);
}
public static long copyLarge(Reader input, Writer output, char[] buffer) throws IOException {
long count;
int n;
for(count = 0L; -1 != (n = input.read(buffer)); count += (long)n) {
output.write(buffer, 0, n);
}
return count;
}
我们可以看到其实IOUtils使用的也是字符流InputStreamReader,但此字符流远没有BufferedReader的效率高,BufferedReader是对Reader的一层包装,它能够读取一行,效率更高,因此使用IOUtis的读取效率要低些。然而IOUtils在写的时候使用了StringBuilderWriter,这个写的效率更高些,比使用StringBuilder一个个append要高许多。因此综上所述总结:BudderReader读取更快,写满,IOUtils读取慢,写更快。
有人可能会提出疑问,既然IOUtis读慢写快,为何不直接也让它读取更快呢,这样不就读写都快了吗?
这个想法是没错的,只是理想很美好,现实很无奈。因为InputStreamReader是专门的字符流,它视为字符流与字节流之间的桥梁。字节流可用于任何类型的对象,包括二进制对象,而字符流只能处理字符或者字符串。 字节流提供了处理任何类型的IO操作的功能,但它不能直接处理Unicode字符,而字符流就可以,两种流各有长短。因此IOUtils为了大众能够通用所以采取了这种设计。