异常信息
java.io.FileNotFoundException: Invalid file path
at java.io.FileOutputStream.<init>(FileOutputStream.java:206)
at java.io.FileOutputStream.<init>(FileOutputStream.java:162)
at com.crazymakercircle.iodemo.socketDemos.NioReceiveServer.processData(NioReceiveServer.java:148)
at com.crazymakercircle.iodemo.socketDemos.NioReceiveServer.startServer(NioReceiveServer.java:101)
at com.crazymakercircle.iodemo.socketDemos.NioReceiveServer.main(NioReceiveServer.java:194)
异常代码
/**
* 处理客户端传输过来的数据
*/
private void processData(SelectionKey key) throws IOException {
Client client = clientMap.get(key.channel());
SocketChannel socketChannel = (SocketChannel) key.channel();
int num = 0;
try {
buffer.clear();
while ((num = socketChannel.read(buffer)) > 0) {
buffer.flip();
//客户端发送过来的,首先是文件名
if (null == client.fileName) {
// 文件名
String fileName = charset.decode(buffer).toString();
String destPath = IOUtil.getResourcePath(NioDemoConfig.SOCKET_RECEIVE_PATH);
File directory = new File(destPath);
if (!directory.exists()) {
directory.mkdir();
}
client.fileName = fileName;
String fullName = directory.getAbsolutePath()
+ File.separatorChar + fileName;
Logger.debug("NIO 传输目标文件:" + fullName);
File file = new File(fullName);
FileChannel fileChannel = new FileOutputStream(file).getChannel();
client.outChannel = fileChannel;
}
//客户端发送过来的,其次是文件长度
else if (0 == client.fileLength) {
// 文件长度
long fileLength = buffer.getLong();
client.fileLength = fileLength;
client.startTime = System.currentTimeMillis();
Logger.debug("NIO 传输开始:");
}
//客户端发送过来的,最后是文件内容
else {
// 写入文件
client.outChannel.write(buffer);
}
buffer.clear();
}
key.cancel();
} catch (IOException e) {
key.cancel();
e.printStackTrace();
return;
}
// 调用close为-1 到达末尾
if (num == -1) {
IOUtil.closeQuietly(client.outChannel);
System.out.println("上传完毕");
key.cancel();
Logger.debug("文件接收成功,File Name:" + client.fileName);
Logger.debug(" Size:" + IOUtil.getFormatFileSize(client.fileLength));
long endTime = System.currentTimeMillis();
Logger.debug("NIO IO 传输毫秒数:" + (endTime - client.startTime));
}
}
原因分析
File file = new File(fullName);
创建了一个File对象,但是fullName代表的文件必须存在。但是根据代码业务逻辑。复制文件时,新文件一般是不存在的,所以必须手动新建文件。
解决方案
File file = new File(fullName);
// 文件不存在则创建文件
if (!file.exists()){
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
这段代码的意思是,创建一个名为file
的File对象,如果该文件不存在,则手动创建,再次运行,则此异常消失。
完整代码
/**
* 处理客户端传输过来的数据
*/
private void processData(SelectionKey key) throws IOException {
Client client = clientMap.get(key.channel());
SocketChannel socketChannel = (SocketChannel) key.channel();
int num = 0;
try {
buffer.clear();
while ((num = socketChannel.read(buffer)) > 0) {
buffer.flip();
//客户端发送过来的,首先是文件名
if (null == client.fileName) {
// 文件名
String fileName = charset.decode(buffer).toString();
String destPath = IOUtil.getResourcePath(NioDemoConfig.SOCKET_RECEIVE_PATH);
File directory = new File(destPath);
if (!directory.exists()) {
directory.mkdir();
}
client.fileName = fileName;
String fullName = directory.getAbsolutePath()
+ File.separatorChar + fileName;
Logger.debug("NIO 传输目标文件:" + fullName);
File file = new File(fullName);
// 文件不存在则创建文件
if (!file.exists()){
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
FileChannel fileChannel = new FileOutputStream(file).getChannel();
client.outChannel = fileChannel;
}
//客户端发送过来的,其次是文件长度
else if (0 == client.fileLength) {
// 文件长度
long fileLength = buffer.getLong();
client.fileLength = fileLength;
client.startTime = System.currentTimeMillis();
Logger.debug("NIO 传输开始:");
}
//客户端发送过来的,最后是文件内容
else {
// 写入文件
client.outChannel.write(buffer);
}
buffer.clear();
}
key.cancel();
} catch (IOException e) {
key.cancel();
e.printStackTrace();
return;
}
// 调用close为-1 到达末尾
if (num == -1) {
IOUtil.closeQuietly(client.outChannel);
System.out.println("上传完毕");
key.cancel();
Logger.debug("文件接收成功,File Name:" + client.fileName);
Logger.debug(" Size:" + IOUtil.getFormatFileSize(client.fileLength));
long endTime = System.currentTimeMillis();
Logger.debug("NIO IO 传输毫秒数:" + (endTime - client.startTime));
}
}
总结
写的不到位的地方还请多多指教!虚心向各位大神学习。