1、BIO方式
/**
* 将文件转换成byte数组
* @param filePath
* @return
*/
public static byte[] File2byteBIO(File tradeFile){
byte[] buffer = null;
try(FileInputStream fis = new FileInputStream(tradeFile);
ByteArrayOutputStream bos = new ByteArrayOutputStream();){
byte[] b = new byte[1024];
int n;
while ((n = fis.read(b)) != -1){
bos.write(b, 0, n);
}
fis.close();
bos.close();
buffer = bos.toByteArray();
}catch (FileNotFoundException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
return buffer;
}
2、BIO-Buffered
public static byte[] File2byteBuffered(File tradeFile){
byte[] buffer = null;
try(FileInputStream fis = new FileInputStream(tradeFile);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
BufferedOutputStream bb = new BufferedOutputStream(bos); ){
byte[] b = new byte[1024];
int n;
while ((n = fis.read(b)) != -1){
bb.write(b, 0, n);
}
fis.close();
bos.close();
buffer = bos.toByteArray();
}catch (FileNotFoundException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
return buffer;
}
3、NIO-拼接数组方式
public static byte[] File2byteNIO(File tradeFile){
byte[] retval = null;
try(FileInputStream fileInputStream = new FileInputStream(tradeFile);) {
FileChannel inChannel = fileInputStream.getChannel();
ByteBuffer buf = ByteBuffer.allocate(1024);
int byteRead = inChannel.read(buf);
int readLength = 0;
while (byteRead != -1){
buf.flip();
byte[] tempval = null;
//以下代码划重点!!!!!!!!
if (retval == null){
retval = new byte[byteRead];
}else{
tempval = retval;
readLength = tempval.length;
retval = new byte[readLength+byteRead];
System.arraycopy(tempval, 0, retval, 0, tempval.length);
}
int i = readLength;
while (buf.hasRemaining()){
byte b = buf.get();
retval[i] = b;
i++;
}
buf.clear();
byteRead = inChannel.read(buf);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return retval;
}
4、NIO2
public static byte[] File2byteNIO2(File tradeFile){
byte[] retval = null;
try(FileInputStream fileInputStream = new FileInputStream(tradeFile);) {
FileChannel inChannel = fileInputStream.getChannel();
ByteBuffer buf = ByteBuffer.allocateDirect((int)inChannel.size()); //文件太大的话这里必然报错
inChannel.read(buf);
retval = new byte[(int)inChannel.size()];
buf.get(retval, 0, buf.remaining());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return retval;
}
文件大小:7M
| 方式 | 10次平均耗时 |
|---|---|
| BIO | 平均:223ms |
| BIO-Buffered | 平均:206ms |
| NIO-拼接数组方式 | 耗时:5467ms |
| NIO2 | 平均:214ms |
总结:拼接数组导致数据频繁的复制移动,影响性能,其他都差不多。
本文对比了四种Java文件读取方式的性能:BIO、带有缓冲的BIO、NIO拼接数组方式以及NIO2。在读取7M大小文件的10次平均耗时中,BIO平均耗时223ms,BIO-Buffered为206ms,NIO2同样为214ms,而NIO-拼接数组方式耗时高达5467ms。性能问题主要出现在NIO的拼接数组方式,由于数据频繁复制移动导致效率降低。其他三种方式表现相近。

872

被折叠的 条评论
为什么被折叠?



