java I/O流的异常问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java I/O流的异常问题相关的知识,希望对你有一定的参考价值。

客户端关闭后,服务器段就出现了下面的异常
java.io.IOException: 您的主机中的软件中止了一个已建立的连接。
at sun.nio.ch.SocketDispatcher.write0(Native Method)
at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:51)
at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)
at sun.nio.ch.IOUtil.write(IOUtil.java:65)
at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:487)
at com.hzx.servlet.P2PServlet$GatewayThread.sendMessage(P2PServlet.java:358)
at com.hzx.servlet.P2PServlet$1.run(P2PServlet.java:127)
if (!en.getKey().contains("SelectionKey"))
GatewayThread g = en.getValue();
g.sendMessage("6");
try sc.write(ByteBuffer.wrap(msg.getBytes()));
key.interestOps(SelectionKey.OP_READ);
catch (IOException e) e.printStackTrace();
removeGateway.add(gid);

如果是使用TCP协议通信,由TCP协议是面向连接。所以当客户端关闭后,由于没有预先告诉服务要销毁连接,客户端关闭时(客户与服务异常断开)服务端就会出现异常(空流情况)。这些都是在意料之内的。

一般的处理方法
对networkStream 处理应该是放在try catch里当出现异常就销毁当前socket连接:
伪代码为
try

networkStream.read();
catch
socket.close();
参考技术A 客户端强制断开链接后,线程继续发送消息会抛异常,因为socket已经断开。 参考技术B 服务器那边没有自动停止连接客户端 参考技术C 如果是客户端主动关闭,忽略即可。追问

可是后台报异常了,而且还是很多重复的异常,这是不是和客户端有关?
还有我想做个if判断,那应该怎么判断sc是否还连接客户端?
谢谢

追答

正常的做法是,客户端发出“关闭连接”请求,然后由服务器执行关闭操作。这个异常就是由于客户端关闭了连接造成的。换一个场景来说,比如客户中断了正在进行的文件下载,也会抛出类似的异常,但最常见的做法是,忽略这个异常。

要判断客户端是否还在线,用心跳机制来实现吧。这种例子网上多的是。

PS:你要加IF干啥?

I/O输入输出流的练习

1.编写TextRw.java的Java应用程序,程序完成的功能是:首先向TextRw.txt中写入自己的学号和姓名,读取TextRw.txt中信息并将其显示在屏幕上。

public class Test01 {

    public static void main(String[] args) {
        //输出流
        String filename="f:/test/TextRw.txt";
        //追加方式
        try 
        {     //追加输入(字节流输入)
                FileOutputStream out = new FileOutputStream(filename,true);
                String str="20142200101 毕研椿";
                //写入数据
                out.write(str.getBytes());
                //释放资源
                out.close();
                System.out.println("写入成功");
                //输入流
                FileInputStream in =new FileInputStream(filename);
                //容器byte[]
                byte[] b =new byte[1024];
                //长度
                int i =0;
                //内容
                StringBuilder chu =new StringBuilder();
                //循环读取
                while((i=in.read(b))>0)
                {
                    //组装数据
                    chu.append(str);
                }
                System.out.println("文件写入内容"+str);
                
                
                //字符流输入
                //输出流
                FileWriter fw = new FileWriter("f:/test/TextRw.txt",true);
                fw.write("20142200101毕研椿");
                fw.close();
                System.out.println("写入成功");
                //输入流
                FileReader fr = new FileReader("f:/test/TextRw.txt");
                char[]c =new char[1024];
                int j=0;
                StringBuilder shur = new StringBuilder();
                while((j=fr.read(c))>0)
                {   //终止读取完单个数组

 

的长度
                    shur.append(new String(c,0,j));
                }
                System.out.println("读取:"+shur);
                fr.close();
        } 
        catch (Exception e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }
        
    
    }

}

 

2.编写IoDemo.java的Java应用程序,程序完成的功能是:首先读取text.txt文件内容,再通过键盘输入文件的名称为iodemo.txt,把text.txt的内容存入iodemo.txt

public class Test02 {

    public static void main(String[] args) {
            File file = new File("f:/text.txt");
        
        //输出流写入一个文件
        try {
                FileOutputStream out = new FileOutputStream("f:/text.txt");
                //写入内容
                String nr = "太难了";
               //兼容任何类型数据
                byte[] b =nr.getBytes();
                out.write(b);
                out.close();
                System.out.println("输出流写入成功");
                //输入流   读  
                FileInputStream in  = new FileInputStream("f:/text.txt");
                // 容器
                byte[] b1 = new byte[1024];
                int i =-1;
                StringBuilder  str = new StringBuilder();
                while(( i =in.read(b1))>0)
                {
                    //组装数据
                    str.append(new String(b1,0,i));
                 }
                System.out.println("读出的信息是:"+str);
                in.close();
                //本质:把原有文件以新的文件名和路径进行复制,然后删除源文件
                file.renameTo(new File("f:/iodemo.txt"));
                System.out.println("修改成功"+file);
                  
             } 
        
        catch (Exception e) {
            
            e.printStackTrace();
        }
    }

}

3.编写BinIoDemo.java的Java应用程序,程序完成的功能是:完成1.doc文件的复制,复制以后的文件的名称为自己的学号姓名.doc。

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class Test03 {

    public static void main(String[] args) {
        //文件复制
        //边读边写
        
        
        try {
                //输入流 读
                FileInputStream in = new FileInputStream("f:/个人简历.docx");
                //byte[]容器
                byte[] b = new byte[1024];
                //长度
                int i =-1;
                //写  输出流
                FileOutputStream out = new FileOutputStream("f:/学号姓名.docx");
                //边读边写
                while((i=in.read(b))>0)
                {
                    //
                    out.write(b,0,i);
                }
                out.close();
                in.close();
                System.out.println("复制成功");
              } 
        catch (Exception e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }

    }

}

 

以上是关于java I/O流的异常问题的主要内容,如果未能解决你的问题,请参考以下文章

Java中的I/O流的基本知识

Java中的I/O流的基本知识

java中finally问题

I/O 文件异常:不包含前两个元素的 ArrayList 值 (JAVA)

i/o流通道被关闭写数据异常

ES 查询时报错 I/O 异常: Request cannot be executed; I/O reactor status: STOPPED