properties和网络编程

1.IO流的分类
    按流的方向划分:
    输入流
    输出流
    
    按流的类型划分:
    传统阻塞式IO----
        对于读写操作,需要借助于线程来进行处理,读写过程中,线程必须处理完毕才能结束!
        wait()等待  /read():读数据(字节:判断结果是否为-1,一直读取!)
        
    非阻塞式IO: IO流的操作(读写某些文件的时候,开启线程)---将这些线程存储在线程池中
                    举例:
                            一个线程池1000个线程,使用完毕归还到线程池中
                            
                    
    字节流
        字节输入流:InputStream
                FileInputStream:文件字节输入流
                BufferedInputStream:字节缓冲输入流
        字节输出流:OutputStream
                FileOutputStream:文件字节输出流
                BufferedOutputStream:字节缓冲输出流
    字符流 
        字符输入流:Reader
                InputStreamReader(InputStream in):字符转换输入流
                    使用平台默认解码的便捷类:
                    FileReader
                    
                    BufferedReader:字符缓冲输入流
        字符输出流:Writer
                OutputStreamWriter(OutputStream out):字符转换输出流
                                FileWriter
                    BufferedWriter:字符缓冲输出流            

2.字符流操作文本文件 读写复制操作有几种方式
        使用基本的字符流:
        InputStreamReader---->FileReader
        OutputStreamWriter--->FileWriter
        1)一次读取一个字符
        2)一次读取一个字符数组
        
        BufferedReader
        BufferedWriter
        1)一次读取一个字符
        2)一次读取一个字符数组
        
        
        3)一次读取一个文本行
        String line = null ;
        String readLine()--->阻塞式方法
        while((line=字符缓冲输入流对象.readLine())!=null){
                使用字符缓冲输出流对象.write(line) ;
                字符缓冲输出流对象.newLine() ;
                字符缓冲输出流对象.flush();
        }
        

3.throws和throw的区别
        throws: 
            1)跟在方法声明上,在方法的后面可以跟多个一次类名,中间逗号隔开
            2)针对throws的异常处理,调用者必须进行显示处理
            3)描述的可能性(执行某段代码可能出现有问题)
            
        throw
            1)用在方法体中使用
            2)对于它的处理,通过方法体中逻辑代码进行处理
            3)throw后面跟的是异常对象名:匿名对象  throw new XXXException() ;
              执行某段代码,一定会抛出异常---交给jvm,将异常日志信息打印控制台上!

4.处理异常有几种方式
            throws:抛出---抛出在方法上
            try...catch...finally:捕获异常(开发中)

5.static关键字特点
        1)随着类的加载而加载
        2)优先于对象存在,不能this共存
        3)可以被多个对象共用,共享
        4)可以类名直接方法:无论这是变量/还是方法,只要被static修饰---都属于 "类成员"

Properties 继承自Hashtable<K,V>---->实现Map<K,V>接口
 *      表示了一个持久的属性集
 *
 *Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。
 *
 * 构造方法
 * public Properties()

//Properties没有泛型,属于Map的一个子实现类
        //使用Map接口的功能操作

        //创建一个属性列表
        Properties properties = new Properties() ;

        //put
        properties.put("张三",30) ;
        properties.put("李四",40) ;
        properties.put("王五",50) ;
        properties.put("赵六",25) ;

        //遍历:Map集合遍历方式: 推荐:keySet()
        Set<Object> keySet = properties.keySet();
        for(Object obj :keySet){
            //通过键获取值
            Object value = properties.get(obj);
            System.out.println(obj+"---"+value);
        }
    }
}

关于属性集合类的特有功能:
 *  添加方法
 *      public Object setProperty(String key,String value)
 *
 *  遍历:
 *          public Set<String> stringPropertyNames()
 *   通过键获取值
 *          public String getProperty(String key)

 public static void main(String[] args) {
        //创建一个属性集合类
        Properties prop = new Properties() ;

        //添加
        prop.setProperty("1","文章") ;
        prop.setProperty("2","高圆圆") ;
        prop.setProperty("3","马伊琍") ;
        prop.setProperty("4","赵又廷") ;
        prop.setProperty("4","王宝强") ;

        //遍历
        Set<String> keySet = prop.stringPropertyNames();
        for(String key:keySet){
            //通过键获取值
            String value = prop.getProperty(key);
            System.out.println(key+"---"+value);
        }
    }
}

关于属性集合类的应用;
 *  1)因为键和值都是String,所以可能将键和值的保存在文本文件或者配置文件中 :加载过程
 *          public void load(Reader reader)throws IOException
 *          public void load(InputStream in)throws IOException
 *
 *  2)将属性集合类中的内容写出到某个文件中:保存过程
 *      public void store(OutputStream out,String comments) throws IOException
 *                  参数1:当前字节输出流
 *                  参数2:给当前属性列表中写入完毕之后,注释的内容
 *   public void store(Writer writer,String comments) throws IOException
 *  将当前项目下的name.txt内容加载到属性集合类中

public class PropertiesDemo3 {
    public static void main(String[] args) throws IOException {

      //  myLoad() ;

     //   mySotre() ;
    }

    //保存:将当前属性集合类中的内容,输出在某个文件中
    private static void mySotre() throws IOException {
        //创建一个属性列表
        Properties prop = new Properties() ;
        prop.setProperty("马伊琍","35") ;
        prop.setProperty("文章","26") ;
        prop.setProperty("姚笛","22") ;
        prop.setProperty("王宝强","35") ;
        prop.setProperty("马蓉","30") ;

        //保存
        prop.store(new FileWriter("userList.txt"),"name's list");

    }

    //加载:将name.txt内容加载到属性集合类中
    private static void myLoad() throws IOException {
        //创建一个属性集合类
        Properties prop = new Properties() ;
        System.out.println(prop);

        //加载
        //字符流
        Reader r = new FileReader("name.txt") ;
        prop.load(r);

        //遍历
        Set<String> keySet = prop.stringPropertyNames();
        for (String key: keySet) {
            String value = prop.getProperty(key) ;
            System.out.println(key+"---"+value);
        }

        //System.out.println(prop);
    }
}

如果我们的配置文件后缀名xx.properties
 *  *  操作步骤:
 *  *          src目录下---->类路径
 *  *          将properties配置文件放置在src目录下

public static void main(String[] args) throws IOException {

        //读取user.properties配置文件: src目录下
        //1)需要获取当前类的字节码文件对象( PropertiesDemo4类中要使用配置文件)
   /*     Class clazz = PropertiesDemo4.class ;
        //2)获取当前类的类加载器
        //Class类的方法:getClassLoader()--->ClassLoader
        ClassLoader classLoader = clazz.getClassLoader();

        //public InputStream getResourceAsStream(String name) :传入当前配置文件-->获取当前配置资源
					的输入流对象(推荐)
        //public URL getResource(String name):传入配置文件名称-->获取当前配置文件的url地址
       //通过类加载将配置文件的内容读取到了流中
        InputStream inputStream = classLoader.getResourceAsStream("user.properties");
*/

        //一步走
        InputStream inputStream = PropertiesDemo4.class.getClassLoader().getResourceAsStream("user.properties");
        //创建属性集合类中
        Properties prop = new Properties() ;
        prop.load(inputStream);

        //System.out.println(prop);
        Set<String> keySet = prop.stringPropertyNames();
        for(String key:keySet){

            System.out.println(key+"---"+prop.getProperty(key));
        }

    }
}

想通过程序的方式:获取本地计算机的这个ip字符串形式以及主机名称?

 java.net.InetAddress:互联协议的ip地址!

    一个具体类中,没有字段,没有构造方法,
        那么这个类只有成员方法,成员方法里面存在静态功能,返回值是它本身!

                单例模式:
                    Runtime
                            private static Runtime currentRuntime = new Runtime() ;
                            private Runtime(){}
                            public static Runtime getRuntime(){
                                    return currentRuntime
}

public static InetAddress getByName(String host):给定主机名称,可以获取互联网ip地址对象!
                        参数:可以传递主机名称/ip地址名称

        public String getHostAddress():获取ip地址字符串形式
        public String getHostName():获取主机名称

public class InetAddressDemo {
    public static void main(String[] args) throws UnknownHostException {
//        InetAddress inetAddress = InetAddress.getByName("LAPTOP-BHL76J0S");
        InetAddress inetAddress = InetAddress.getByName("10.12.152.131");

        //获取ip地址字符串文本
        String ip = inetAddress.getHostAddress();
        System.out.println(ip);//10.12.152.129

        //获取主机名称
        String hostName = inetAddress.getHostName();
        System.out.println(hostName);//LAPTOP-BHL76J0S

        //LAPTOP-4IJ0OFL4
    }
}

UDP协议发送端的实现步骤: (不需要建立连接通道,以"数据报包"的方式发送数据)
 *  DatagramSocket表示用来发送和接收"数据报包"的套接字
 *  *  1)创建发送端的Socket:  DatagramSocket
 *  *          public DatagramSocket() throws SocketException{}
 *  *  2) 创建 "数据报包"对象
 *  *          public DatagramPacket(byte[] buf,int length,InetAddress address,int port)
 *  *  3)发送数据报包
 *  *          public void send(DatagramPacket p) throws IOException
 *  *
 *  *  4)释放资源
 *  *          close()关闭socket对象

public class SendDemo {
    public static void main(String[] args) throws IOException {
        //创建发送端的Socket:  DatagramSocket
        DatagramSocket ds = new DatagramSocket() ;

        //创建 "数据报包"对象
//         public DatagramPacket(byte[] buf,int length,InetAddress address,int port)
        //参数1:包的数据--字节数组
        //参数2:包的长度
        //参数3:ip地址
        //参数4:端口号
        String messageStr = "hello,UDP,我来了" ;
        byte[] bytes = messageStr.getBytes();
        int length = bytes.length ;
        InetAddress inetAddress = InetAddress.getByName("10" +
                ".12.152.129");
        int port = 10086 ;
        DatagramPacket dp = new DatagramPacket(bytes, length, inetAddress, port);

        //3)发送数据
        ds.send(dp);
        System.out.println("当前数据已经发送...");

        //4)释放资源
        ds.close();
    }
}

UDP协议接收端实现
 *
 * 1)创建接收端的Socket
 *      public DatagramSocket(int port) throws SocketException:绑定端口号
 *
 * 2)数据一个数据报包对象:DatagramPacket
 *      接收容器
 *              public DatagramPacket(byte[] buf, int length) :获取的是缓冲区的数据(不是真实数据)
 *                  一般情况:byte[] bytes = new byte[1024] ; 自定义字节缓冲区
 *
 * 3)接收
 *     public void receive(DatagramPacket p):阻塞式方法:在接收数据之前,一直处于阻塞状态,直到
 *     当前接收端监听客户端口号了
 * 4) 获取缓冲区的传递的真实数据
 *      public byte[] getData():获取真实的字节数组
 *      public int getLength():获取实际长度
 *      将获取的字节数据---->String(byte[] bytes,int offset,int length)
 *      获取哪个发送端传递的数据:ip 文本形式:
 *              public InetAddress getAddress()
 *                          IntegerAddss--->public String getHostAddress()
 *
 * 5)使用完毕,关闭接收端
 *
 *
 * 接收端不能运行多次,否则出现异常了,端口号被占用!

public class ReceiveDemo {
    public static void main(String[] args) throws IOException {

        System.out.println("接收端等待发送数据...");

        //创建接收端的Socket
        DatagramSocket ds = new DatagramSocket(10086) ;

        // 接收容器:数据报包
        //定义一个字节缓冲区
        byte[] bytes = new byte[1024] ;
        int length = bytes.length ;
        DatagramPacket dp = new DatagramPacket(bytes,length) ;

        //接收
        ds.receive(dp);
        System.out.println("已经获取发送数据准备解析...");


        //解析真实数据
        /*
        * public byte[] getData():获取真实的字节数组
         *      public int getLength():获取实际长度*/
        byte[] bytes2 = dp.getData();
        int len = dp.getLength();
        //获取ip地址
        String ip = dp.getAddress().getHostAddress();
        String receiveMsgStr = new String(bytes2,0,len) ;

        System.out.println("data from " + ip +"and content is:  "+receiveMsgStr);

        //关闭资源
        ds.close();

    }
}

Udp接收端不断的接收数据,接收端一般不关闭(模拟真实场景)

 udp发送端不断的键盘录入数据,当前录入是 "over/886",结束,接收端不断的接收数据!
 *          键盘录入数据采用的是:BufferedReader的readLine()功能来操作

public class ReceiveDemo {
    public static void main(String[] args)  throws  Exception{
        try {
            System.out.println("等待接收");
            DatagramSocket ds =new DatagramSocket(10010) ;


        while(true){
            //创建接收端的Socket对象
                //创建数据报包:接收容器
                DatagramPacket dp = new DatagramPacket(new byte[1024],new byte[1024].length) ;
                //接收
                ds.receive(dp);

                //准备解析真实数据
                String str = new String(dp.getData(),0,dp.getLength()) ;
                String ip = dp.getAddress().getHostAddress() ;
                System.out.println("data from: "+ip+" and content is: "+str );

//                ds.close(); //接收端不需要关闭
            }
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }


    }
}udp发送端不断的键盘录入数据,当前录入是 "over/886",结束,接收端不断的接收数据!
 *          键盘录入数据采用的是:BufferedReader的readLine()功能来操作
 */
public class SendDemo {
    public static void main(String[] args) {
        //创建一个字符缓冲输入流

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in)) ;
        //创建一个送端的Socket对象
        DatagramSocket ds = null ;

        try {
             ds = new DatagramSocket() ;
            String line = null ;
            while((line=br.readLine())!=null){
                //自定义结束条件
                if("886".equals(line)){
                    break ;
                }
                //创建数据报包
                DatagramPacket dp = new DatagramPacket(
                        line.getBytes(),
                        line.getBytes().length,
                        InetAddress.getByName("10.12.152.129"),
                        10010);
                ds.send(dp);
            }
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(ds!=null){
                ds.close();
            }
        }
    }
}

如何使用udp方式在一个窗口下进行聊天
 *
 *
 *  需要两条线程:发送端发消息的线程
 *               接收端接收消息的线程
 *
 *        创建线程的方式:(除过线程池)
 *              1)继承自Thread类
 *              2)实现Runnable接口 ---> 能够多个线程占用的 内存空间(共享共用)
 *                          代理----静态代理模式

发送端的资源类

接收端的资源类对象

public class ChatRoom {
    public static void main(String[] args) throws Exception{

        //创建两端的Socket对象
        //发送端:
        DatagramSocket ds = new DatagramSocket() ;
        //接收端
        DatagramSocket ds2 = new DatagramSocket(12306) ;

        //创建资源类对象
        //发送端的资源类以及接收端端的子类
        SendThread st  = new SendThread(ds) ;
        ReceiveThread rt = new ReceiveThread(ds2) ;

        //创建线程对象
        Thread t1 = new Thread(st) ;
        Thread t2 = new Thread(rt) ;
        t1.start();
        t2.start();


    }
}

发送端的资源类
 */
public class SendThread implements  Runnable {

    private DatagramSocket ds ;
    public SendThread(DatagramSocket ds){
        this.ds = ds ;
    }


    @Override
    public void run() {
        try {
            //不断键盘录入数据
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in)) ;
            String line = null ;
            while((line=br.readLine())!=null){
                if("over".equals(line)){
                    break ;
                }

                //创建数据报包
                DatagramPacket dp = new DatagramPacket(line.getBytes(),
                        line.getBytes().length,
                        InetAddress.getByName("10.12.152.129"),
                        12306);

                //发送数据
                ds.send(dp) ;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(ds!=null){
                ds.close();
            }
        }

    }
}
接收端的资源类对象
 */
public class ReceiveThread implements Runnable {

    private DatagramSocket ds ;
    public ReceiveThread(DatagramSocket ds){
        this.ds = ds ;
    }

    @Override
    public void run() {

        try {
            while(true){
                //创建接收端的Socket对象
                //创建数据报包:接收容器
                DatagramPacket dp = new DatagramPacket(new byte[1024],new byte[1024].length) ;
                //接收
                ds.receive(dp);

                //准备解析真实数据
                String str = new String(dp.getData(),0,dp.getLength()) ;
                String ip = dp.getAddress().getHostAddress() ;
                System.out.println("data from: "+ip+" and content is: "+str );

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        //接收不需要关闭
    }
}

TCP/IP协议:客户端发送的过程
 *
 *  1)创建客户端的Socket
 *          public Socket(String host,int port) throws UnknownHostException,IOException
 *  2)public OutputStream getOutputStream()throws IOException
 *          获取当前客户端对象所在的通道内的输出流对象
 *  3)使用当前通道内的字节输出流 写数据过去
 *  4)释放资源

public class ClientDemo {
    public static void main(String[] args) throws IOException {

        //1)创建客户端的Socket
        Socket socket = new Socket("10.12.152.129",6666) ;


        //2)获取当前客户端对象所在的通道内的输出流对象
        OutputStream outputStream = socket.getOutputStream();

        //3)写数据
        outputStream.write("hello,TCP,我来了".getBytes());

        //4)释放资源
        socket.close();
    }
}

服务器端
 *  1)创建服务器端的Socket  :此类实现服务器套接字
 *      public ServerSocket(int port)
 *              throws IOException
 *  2)监听客户端连接
 *      public Socket accept()
 *               throws IOException
 *
 * 3)     通过监听到的客户端对象 获取通道的输入流
 *      public InputStream getInputStream()
 *
 *
 * 4)关闭资源
 *      服务器端关闭

public class ServerSocketDemo {
    public static void main(String[] args) throws IOException {

        //创建服务器端的Socket
        ServerSocket ss = new ServerSocket(6666) ; //一旦能成功,就立即建立通道
        System.out.println("服务器正在等待连接...");

        //2)监听并获取客户端的socket对象
        Socket socket = ss.accept(); //阻塞式方法 如果没有监听到,一直等
        //3)获取通道内的输入流
        InputStream inputStream = socket.getInputStream();
        //一次读取一个字节数组
        byte[] bytes = new byte[1024] ;
        int len = inputStream.read(bytes);
        String str = new String(bytes,0,len) ;

        //通过监听到客户端的socket对象获取ip地址
        String ip = socket.getInetAddress().getHostAddress();
        System.out.println("data from :" +ip +" content is :"+str);
        System.out.println("服务器端接收完毕...");



        //释放资源
        ss.close();

    }
}

网络编程的三要素
        ip地址:点分十进制法
            私人地址:(C类)
            回环地址:127.0.0.1
        
        端口号:(360软件插件---可以查本机软件所有端口号)
            0-65535:(0-1024暴露端口号)
            mysql:3306
            tomcat:8080
            redis:
                no-sql数据库:6375...
        
        协议:tcp/udp协议

2.UDP发送端和接收端如何实现:操作步骤
    发送端
            1)创建DatagramSocket对象
            DatagramSocket ds = new DatagramSocket() ;
            2)创建数据报包对象
            byte[] bytes = "hello,udp".getBytes() ;
            int length = bytes.length;
            DatagramPacket dp = new DatagramPacket(
                bytes,//包数据
                length,//包长度
                InetAddress.getByName("10.12.152.129"),//绑定本机的ip地址对象
                10086 //端口号
            ) ;
            
            3)发送数据报包
            ds.send(dp) ;
            
            4)释放资源
            ds.close() ;
            
    接收端:
        1)创建接收端的socket对象
        DatagramSocket ds = new DatagramSocket(10086) ;
        2)创建接收容器(数据报包)
        byte[] bytes = new byte[1024] ;
        int length = bytes.length ;
        DatagramPacket dp = new DatagramPacket(bytes,length) ;
        
        3)接收
        ds.receive(dp) ;
        
        4)解析真实数据
        byte[] myBytes = dp.getData() ; //实际字节数组
        //获取实际长度
        int len = dp.getLength();
        //转换成字符串内容
        String str = new String(myBytes,0,len) ;
        String ip = dp.getInetAddress().getHostAddress() ;
        //输出发送端的ip以及发送的内容...
        

3.TCP发送端和接收端如何实现:操作步骤
        TCP客户端
            1)创建客户端的socket对象
            Socket socket = new Socket("10.12.152.129",10010) ;
            2)获取通道内的输出流对象(字节输出流)
            OutputStream out = socket.getOutputStream() ;
            3)写数据到通道内中
            out.write("hello,TCP".getBytes()) ;
            
            4)关闭资源
            socket.close() ;
            
        TCP服务器端:
            1)创建服务器端的Socket对象
            ServerSocket ss = new ServerSocket(10010) ;
            2)侦听并获取所在的客户端对象
            Socket socket = ss.accpet() ;//侦听前,该方法一直阻塞
            3)获取通道内容输入流
            InputStream in = socket.getInputStream() ;
            4)读数据
            byte[] bytes = new byte[1024] ;
            int len = in.read(bytes) ;
            5)获取客户端发送的确认字符
            String str = new String(bytes,0,len) ;
            String ip = socket.getInetAddress().getHostAddress() ;
            //获取客户端地址ip以及发送内容
            
            
            反馈---->

4.UDP和TCP的区别
        1)是否是需要建立连接通道
            UDP:属于无连接方式发送----> 数据报包的方式来发送(包报文...)
            TCP:需要建立连接通道(需要三次握手)
        2)是否可靠安全
            UDP:属于不可靠连接,不安全,执行效率高
            TCP:属于可靠连接,安全的,执行效率低
            
        3)发送数据大小是否有限制
            UDP:发送的数据大小限制
            TCP:
            最基本的字节流发送和读取,
            可以支持数据无限制(占用内存比较大的数据:视频(大字节类型Blob:支持4G))
                    
                
        
        
        
        

5.获取字节码文件的方式
    三种
     Object的getClass()
     任意Java类型的class属性
     Class.forName("包名.类名") ;
     com.qf.io_01.FileOutputStreamDemo :一个类或者接口的全限定名称
     com.qf.io_01.FileOutputStreamDemo

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值