【发布时间】:2019-01-23 01:36:45
【问题描述】:
我是 Netty 的新手。文件传输有一个问题让我困惑了好几天。我想将 图像 文件从客户端发送到服务器。
下面的代码是可执行的。但是只有我强行shutdown服务器才能正常打开接收到的图片文件。否则,它会显示“您似乎没有查看此文件的权限。请检查权限并重试”。因此,我想在 ByteBuf 中没有数据时使用 ByteBuf.isReadable() 关闭文件输出流,但 ServerHandler 中的方法 channelRead 中的 else 块永远无法到达。没用。
另外,如果发送文本文件,在服务器存活时可以正常打开。 我不想每次传输后都关闭服务器。请给我一些解决它的建议。
这是 FileClientHandler
public class FileClientHandler extends ChannelInboundHandlerAdapter {
private int readLength = 8;
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
sendFile(ctx.channel());
}
private void sendFile(Channel channel) throws IOException {
File file = new File("C:\\Users\\xxx\\Desktop\\1.png");
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
for (;;) {
byte[] bytes = new byte[readLength];
int readNum = bis.read(bytes, 0, readLength);
// System.out.println(readNum);
if (readNum == -1) {
bis.close();
fis.close();
return;
}
sendToServer(bytes, channel, readNum);
}
}
private void sendToServer(byte[] bytes, Channel channel, int length)
throws IOException {
channel.writeAndFlush(Unpooled.copiedBuffer(bytes, 0, length));
}
}
这是文件服务器处理程序
public class FileServerHandler extends ChannelInboundHandlerAdapter {
private File file = new File("C:\\Users\\xxx\\Desktop\\2.png");
private FileOutputStream fos;
public FileServerHandler() {
try {
if (!file.exists()) {
file.createNewFile();
} else {
file.delete();
file.createNewFile();
}
fos = new FileOutputStream(file);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
try {
ByteBuf buf = (ByteBuf) msg;
if (buf.isReadable()) {
buf.readBytes(fos, buf.readableBytes());
fos.flush();
} else {
System.out.println("I want to close fileoutputstream!");
buf.release();
fos.flush();
fos.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
【问题讨论】:
-
似乎某些进程锁定了文件:如果您在基于 unix 的系统中工作,请尝试检查文件权限。或者在文件传输完成后尝试关闭通道(在服务器和客户端上)。但首先,只需传输后尝试关闭通道
-
感谢您的评论。我在 Windows 上工作。对我来说关键是我怎么知道文件传输是在 ServerHandler 中完成的。我在 ClientHandler 中发送后尝试关闭通道,如下所示:fis.getChannel().close();。但这是徒劳的。你知道为什么文本文件可以打开而图片不能吗?