feat(decorator-pattern): 实现文件输入流的缓冲装饰器- 新增 MyFileInputStreamBuffer 类,用于缓冲文件输入流
- 创建 App 类,演示使用缓冲装饰器读取文件的性能提升- 添加 .gitignore 文件,忽略 IDE 和构建工具的配置文件- 创建 Maven 项目配置文件 pom.xml
This commit is contained in:
commit
0ab8e423de
38
.gitignore
vendored
Normal file
38
.gitignore
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea/modules.xml
|
||||
.idea/jarRepositories.xml
|
||||
.idea/compiler.xml
|
||||
.idea/libraries/
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### Eclipse ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
||||
### Mac OS ###
|
||||
.DS_Store
|
17
pom.xml
Normal file
17
pom.xml
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>feng.yu</groupId>
|
||||
<artifactId>shengsheng_study</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
</project>
|
58
src/main/java/decorator_pattern/app/App.java
Normal file
58
src/main/java/decorator_pattern/app/App.java
Normal file
@ -0,0 +1,58 @@
|
||||
package decorator_pattern.app;
|
||||
|
||||
import decorator_pattern.tech.MyFileInputStreamBuffer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.time.Instant;
|
||||
|
||||
/**
|
||||
* @author weizhenfeng韦振凤
|
||||
* @version 1.0
|
||||
* @description: TODO
|
||||
* @date 2025/6/2 下午9:51
|
||||
*/
|
||||
public class App {
|
||||
|
||||
public static void main(String[] args) {
|
||||
unOpt();
|
||||
|
||||
opt();
|
||||
|
||||
}
|
||||
|
||||
private static void opt() {
|
||||
File file = new File("F:\\BigData\\交易模型\\交易模型-存款交易信息.xlsx");
|
||||
long startTime = Instant.now().toEpochMilli();
|
||||
|
||||
try (
|
||||
InputStream fis = Files.newInputStream(file.toPath());
|
||||
InputStream bufferedStream = new MyFileInputStreamBuffer(fis) // 使用缓冲装饰器
|
||||
) {
|
||||
while (bufferedStream.read() != -1) {
|
||||
// 空循环
|
||||
}
|
||||
System.out.println("缓冲读取耗时(ms): " + (Instant.now().toEpochMilli() - startTime));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void unOpt() {
|
||||
File file = new File("F:\\BigData\\交易模型\\交易模型-存款交易信息.xlsx");
|
||||
long epochMilli = Instant.now().toEpochMilli();
|
||||
try (FileInputStream fileInputStream = new FileInputStream(file)) {
|
||||
while (fileInputStream.read() != -1) {
|
||||
if (fileInputStream.read() == -1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
System.out.println(Instant.now().toEpochMilli() - epochMilli);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
package decorator_pattern.tech;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class MyFileInputStreamBuffer extends InputStream {
|
||||
|
||||
private final InputStream decoratedInputStream; // 被装饰的InputStream
|
||||
private final byte[] buffer = new byte[8192]; // 缓冲区
|
||||
private int position; // 当前缓冲区位置
|
||||
private int count; // 缓冲区有效字节数
|
||||
|
||||
// 使用InputStream而不是具体FileInputStream,提高通用性
|
||||
public MyFileInputStreamBuffer(InputStream inputStream) {
|
||||
this.decoratedInputStream = inputStream;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
// 缓冲区为空时填充
|
||||
if (position >= count) {
|
||||
if (!fillBuffer()) {
|
||||
return -1; // 流结束
|
||||
}
|
||||
}
|
||||
// 从缓冲区读取一个字节
|
||||
return buffer[position++] & 0xFF;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
int totalRead = 0;
|
||||
while (len > 0) {
|
||||
// 缓冲区为空则填充
|
||||
if (position >= count) {
|
||||
if (!fillBuffer()) {
|
||||
return totalRead == 0 ? -1 : totalRead;
|
||||
}
|
||||
}
|
||||
|
||||
// 计算本次可读取的字节数
|
||||
int available = count - position;
|
||||
int toRead = Math.min(available, len);
|
||||
|
||||
// 从缓冲区复制数据
|
||||
System.arraycopy(buffer, position, b, off, toRead);
|
||||
|
||||
// 更新位置和长度
|
||||
position += toRead;
|
||||
off += toRead;
|
||||
len -= toRead;
|
||||
totalRead += toRead;
|
||||
}
|
||||
return totalRead;
|
||||
}
|
||||
|
||||
private boolean fillBuffer() throws IOException {
|
||||
position = 0;
|
||||
count = decoratedInputStream.read(buffer);
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
decoratedInputStream.close(); // 委托给被装饰对象
|
||||
position = count = 0; // 重置缓冲区状态
|
||||
}
|
||||
|
||||
// 可选:重写其它方法提升性能
|
||||
@Override
|
||||
public long skip(long n) throws IOException {
|
||||
if (n <= 0) return 0;
|
||||
|
||||
// 先使用缓冲区中的可用数据
|
||||
int availableInBuffer = count - position;
|
||||
if (availableInBuffer >= n) {
|
||||
position += (int)n;
|
||||
return n;
|
||||
}
|
||||
|
||||
// 需要跳过超过缓冲区的内容
|
||||
position = count; // 消耗掉当前缓冲区
|
||||
return availableInBuffer + decoratedInputStream.skip(n - availableInBuffer);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user