最近在写一个 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 )
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.