最近在写一个 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 的代码,解压到一个临时目录下 |