最近在写一个 Netty 的小工具遇到一个问题。
想读取程序本 Jar 包内的资源文件(在类目录下的 /static/下,打包后在 jar 包里)
在 IDE 里面跑的时候因为是在 /target/下可以用 new File()的形式直接访问,但是打包为 Jar 包后,该文件就不能用 new File(path) 的形式访问了。
但是纠结的是 Netty 提供的文件传输需要一个 FileChannel, 一般都是从 RandomAccessFile 获得的,
这个 RandomAccessFile 只能从 File 获得。
大概如下:
public void handle(ChannelHandlerContext ctx, FullHttpRequest msg, String filePath) throws IOException, URISyntaxException {
filePath = filePath.substring(1);
URL url = this.getClass().getClassLoader().getResource(filePath);
File file = new File(url.getFile().replace("%20"," "));
RandomAccessFile accessFile = new RandomAccessFile(file, "r");
HttpResponse response = new DefaultHttpResponse(msg.protocolVersion(), HttpResponseStatus.OK);
String contentType = parseContentType(filePath);
response.headers().set(HttpHeaderNames.CONTENT_TYPE, contentType);
long length = file.length();
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, length);
ctx.write(response);
ctx.write(new DefaultFileRegion(accessFile.getChannel(), 0, file.length()));
ChannelFuture channelFuture = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
}
PS : 我知道可以用 getResourceAsStream 拿到 InputStream ,可以转为 channel
ReadableByteChannel readableByteChannel = Channels.newChannel(url.openStream());
但是这样好像不能拿到 size,也不能利用 FileChannel 的 tranfer 方法进行零拷贝了;
如果直接用 InputStream 拿数据,是阻塞 IO,和 Netty 不搭。
求大佬赐教![哭] (顺便 github 地址: https://github.com/woodyDM/simplesocks-java )
1
sagaxu 2019-05-31 11:56:05 +08:00 via Android
jar 包里读文件是阻塞操作,没有特别好的办法。建议参考一下 vertx 的代码,解压到一个临时目录下
|