BufferedReader(字符读入处理流)读取文件中的内容
BufferReader适合需要对文件中的内容进行处理的情况
private StringBuilder getFileContent(MultipartFile oneFile) {//MultipartFile是spring文件上传的工具类
StringBuilder fileContent = new StringBuilder("");
//try-with-resource,将自动关闭resource(前提是其中的类实现AutoCloseable接口)
try (InputStream is = oneFile.getInputStream()
; InputStreamReader isr = new InputStreamReader(is, "gb2312")//gb2312是win下txt编码模式
; BufferedReader br = new BufferedReader(isr)
) {
String temp = null; //用于接收每读一行的内容
while ((temp = br.readLine()) != null) { //null判断文件读取是否结束,不能用temp的长度判断
fileContent.append(temp);
}
} catch (IOException e) {
e.printStackTrace();
}
return fileContent;
}
当只需要对文件进行输入输出时,可以使用字节节点流(如FileInputStream、FileOutputStream)
private void writeFile(MultipartFile multipartFile, String path) throws IOException {
// 如果没有文件上传,MultipartFile也不会为null,可以通过调用getSize()方法获取文件的大小来判断是否有上传文件
if (multipartFile.getSize() <= 0) {
return;
}
File file = new File(path);
if (!file.exists()) {
file.mkdir();
System.out.println(file.getPath() + "不存在,现已被创建");
}
file = new File(path, multipartFile.getOriginalFilename());
//下面两行语句都可以完成文件的写入,且都是使用的字节节点流
// multipartFile.transferTo(file);
//org.apache.commons.io.IOUtils,其方法体的主要内容参考下面的copyLarge
IOUtils.copy(multipartFile.getInputStream(),new FileOutputStream(file));
}
//copy方法的主要内容。buffer为读入缓存数组的大小
public static long copyLarge(final InputStream input, final OutputStream output, final byte[] buffer)
throws IOException {
long count = 0;
int n;
while (EOF != (n = input.read(buffer))) {
output.write(buffer, 0, n);
count += n;
}
return count;
}
使用 NIO 的 FileChannel 来读写文件(建议大文件场景下使用)
/**
* 通过Nio方式去读取内容
* <p>
* 1.通过FileInputStream创建通道
* 2.创建ByteBuffer缓冲区
* 3.将数据读取到缓冲区
*
* @param txtPath
*/
private static StringBuilder readContextByNio(String txtPath) throws IOException {
StringBuilder context = new StringBuilder("");
//1
try (FileInputStream fis = new FileInputStream(txtPath)
; FileChannel channel = fis.getChannel()
) {
//2
int byteCapacity = 128;
ByteBuffer bf = ByteBuffer.allocate(byteCapacity);
//缓冲区重要变量大小关系:
//mark(缓冲区中执行reset操作时,position应该置于的位置) <= position(可读写数据的起始位置) <= limit(不可读写的起始位置) <= capacity(缓冲区最大数据容量)
System.out.println("限制是:" + bf.limit() + "容量是:" + bf.capacity() + "位置是:" + bf.position());
//3
int length = -1;
while ((length = channel.read(bf)) != -1) {
/*
* 注意,读取后,将位置置为0,将limit置为容量, 以备下次读入到字节缓冲中,从0开始存储
*/
bf.clear();
byte[] bytes = bf.array();
String s = new String(bytes, 0, length, "gbk");//在文件读取时是按字节读取的,所以此处设置编码不会乱码
context.append(s);
System.out.println("限制是:" + bf.limit() + "容量是:" + bf.capacity() + "位置是:" + bf.position());
}
}
return context;
}
/**
* 使用NIO方式完成数据的读取与写入
* @param txtPath
*/
private static String RWContextByNio(String txtPath) throws IOException {
try ( //读入
FileInputStream fis = new FileInputStream(txtPath)
; FileChannel inChannel = fis.getChannel()
//写出
; FileOutputStream fos = new FileOutputStream(new File(txtPath).getParent() + "/out.txt")
; FileChannel outChannel = fos.getChannel()
) {
ByteBuffer bf = ByteBuffer.allocate(128);
int length = -1;
while ((length = inChannel.read(bf)) != -1) {
bf.flip();
int outlength = 0;
while ((outlength = outChannel.write(bf)) != 0) {
System.out.println("读," + length + "写," + outlength);
}
//清空缓冲区,使得整个缓冲区均可用
bf.clear();
}
}
return "success";
}