Java-day27(IO流与网络编程)

对象流( ObjectInputStream和OjbectOutputSteam )

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Person类:

package com.acoffee.java1;

import java.io.Serializable;

/**
 * Person需要满足下列的要求才能满足序列化
 * 1.需要实现接口:Serializable
 * 2.当前类提供一个全局变量:serialVersionUID
 * 3.除了当前Person类需要实现Serializable接口之外,
 *   还必须保证其内部所有的属性也必须是可序列化的。
 *   (默认情况下,基本数据类型可序列化)
 *
 *   ObjectOutputStream和ObjectInputStream
 *   不能序列化static和transient修 饰的成员变量
 *
 * @author acoffee
 * @create 2020-10-20 19:31
 */
public class Person implements Serializable {

    public static final long serialVersionUID = -123131234353L;

    private int age;
    private String name;
    private int id;

    public long getSerialVersionUID() {
        return serialVersionUID;
    }

    public Person() {

    }

    public Person(int age, String name, int id) {

        this.age = age;
        this.name = name;
        this.id = id;
    }
}

package com.acoffee.java1;

import org.junit.Test;

import java.io.*;

/**
 * 对象流的使用
 * 1.ObjectInputStream 和 ObjectOutputStream
 * 2.作用:用于存储和读取基本数据类型数据或对象的处理流。它的强大之处就是可以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来。
 * <p>
 * 3.要想一个java对象是可序列化的,需要满足相应的要求。见Person.java
 * <p>
 * 4.序列化机制:
 * 对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种
 * 二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。
 * 当其它程序获取了这种二进制流,就可以恢复成原来的Java对象。
 *
 * @author acoffee
 * @create 2020-10-20 19:09
 */
public class ObjectInputOutputStream {
    /*
       序列化过程:将内存中的java对象保存到磁盘中或通过网络传播出去
       使用ObjectOutputStream实现

    */
    @Test
    public void testObjectOutputStream() {
        ObjectOutputStream oos = null;
        try {
            oos = new ObjectOutputStream(new FileOutputStream("hello.dat"));

            oos.writeObject(new String("我爱北京天安门"));
            oos.flush();//刷新操作

            oos.writeObject(new Person(23, "frank",0));
            oos.flush();


        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (oos != null) {
                    oos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }

    /*
     * 反序列化:将磁盘文件的对象还原为内存中的一个java对象
     * 使用ObjectInputStream来实现
     * */
    @Test
    public void testObjectInputStream() {
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream("hello.dat"));

            Object obj = ois.readObject();
            String str = (String) obj;

            Person p = (Person) ois.readObject();

            System.out.println(str);
            System.out.println(p);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                if (ois != null) {
                    ois.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }

}

在这里插入图片描述

随机存取文件流(RandomAccessFile 类)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
RandAccessFile的使用

  • 1.RandomAccessFile直接继承于java.lang.Object类,实现了 DataInput和DataOutput接口
  • 2.RandomAccessFile既可以作为一个输入流,又可以作为一个输出流
  • 3.如果RandomAccessFile作为输出流存在,谢楚道的文件如果不存在,则在执行过程中自动创建,如果写出到的文件存在时,则会对原有文件内容进行覆盖(从头开始覆盖)
  • 可以通过相关操作实现插入的操作

RandomAccessFile作为输入流:

    @Test
    public void test1() throws IOException {
        RandomAccessFile raf1 = null;
        RandomAccessFile raf2 = null;
        try {
            //1.
            raf1 = new RandomAccessFile(new File("爱情与友情.jpg"), "r");
            raf2 = new RandomAccessFile(new File("爱情与友情5.jpg"), "rw");

            //2.
            byte[] buffer = new byte[1024];
            int len;
            while ((len = raf1.read(buffer)) != -1) {
                raf2.write(buffer, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (raf1 != null)
                    //3.
                    raf1.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (raf2 != null)
                    raf2.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

作输出流时(如果有内容 会对原有文件内容进行覆盖):

    @Test
    public void test2() throws IOException {
        RandomAccessFile raf = new RandomAccessFile(new File("hello.txt"), "rw");

        raf.seek(3);//将指针调到角标3的位置(从角标3开始覆盖)
        raf.write("frank".getBytes());

        raf.close();

    }

执行前:
在这里插入图片描述
执行后:
在这里插入图片描述

练习:RandomAccessFile实现数据的插入

    /*
    使用RandomAccessFile实现数据的插入效果
     */
    @Test
    public void test3() throws IOException {

        RandomAccessFile raf1 = new RandomAccessFile("hello.txt","rw");

        raf1.seek(3);//将指针调到角标为3的位置
        //保存指针3后面的所有数据到StringBuilder中
        StringBuilder builder = new StringBuilder((int) new File("hello.txt").length());
        byte[] buffer = new byte[20];
        int len;
        while((len = raf1.read(buffer)) != -1){
            builder.append(new String(buffer,0,len)) ;
        }
        //调回指针,写入“xyz”
        raf1.seek(3);
        raf1.write("xyz".getBytes());

        //将StringBuilder中的数据写入到文件中
        raf1.write(builder.toString().getBytes());

        raf1.close();

        //思考:将StringBuilder替换为ByteArrayOutputStream
    }

NIO.2中Path、 Paths、Files类的使用

在这里插入图片描述
随着 JDK 7 的发布,Java对NIO进行了极大的扩展,增强了对 文件处理和文件系统特性的支持,以至于我们称他们为 NIO.2。 因为 NIO 提供的一些功能,NIO已经成为文件处理中越来越重要的部分。
在这里插入图片描述

/**
 * 1. jdk 7.0 时,引入了 Path、Paths、Files三个类。
 * 2.此三个类声明在:java.nio.file包下。
 * 3.Path可以看做是java.io.File类的升级版本。也可以表示文件或文件目录,与平台无关
 * <p>
 * 4.如何实例化Path:使用Paths.
 * static Path get(String first, String … more) : 用于将多个字符串串连成路径
 * static Path get(URI uri): 返回指定uri对应的Path路径
 *
 * @author shkstart
 * @create 2019 下午 2:44
 */
public class PathTest {

    //如何使用Paths实例化Path
    @Test
    public void test1() {
        Path path1 = Paths.get("d:\\nio\\hello.txt");//new File(String filepath)

        Path path2 = Paths.get("d:\\", "nio\\hello.txt");//new File(String parent,String filename);

        System.out.println(path1);
        System.out.println(path2);

        Path path3 = Paths.get("d:\\", "nio");
        System.out.println(path3);
    }

    //Path中的常用方法
    @Test
    public void test2() {
        Path path1 = Paths.get("d:\\", "nio\\nio1\\nio2\\hello.txt");
        Path path2 = Paths.get("hello.txt");

//		String toString() : 返回调用 Path 对象的字符串表示形式
        System.out.println(path1);

//		boolean startsWith(String path) : 判断是否以 path 路径开始
        System.out.println(path1.startsWith("d:\\nio"));
//		boolean endsWith(String path) : 判断是否以 path 路径结束
        System.out.println(path1.endsWith("hello.txt"));
//		boolean isAbsolute() : 判断是否是绝对路径
        System.out.println(path1.isAbsolute() + "~");
        System.out.println(path2.isAbsolute() + "~");
//		Path getParent() :返回Path对象包含整个路径,不包含 Path 对象指定的文件路径
        System.out.println(path1.getParent());
        System.out.println(path2.getParent());
//		Path getRoot() :返回调用 Path 对象的根路径
        System.out.println(path1.getRoot());
        System.out.println(path2.getRoot());
//		Path getFileName() : 返回与调用 Path 对象关联的文件名
        System.out.println(path1.getFileName() + "~");
        System.out.println(path2.getFileName() + "~");
//		int getNameCount() : 返回Path 根目录后面元素的数量
//		Path getName(int idx) : 返回指定索引位置 idx 的路径名称
        for (int i = 0; i < path1.getNameCount(); i++) {
            System.out.println(path1.getName(i) + "*****");
        }

//		Path toAbsolutePath() : 作为绝对路径返回调用 Path 对象
        System.out.println(path1.toAbsolutePath());
        System.out.println(path2.toAbsolutePath());
//		Path resolve(Path p) :合并两个路径,返回合并后的路径对应的Path对象
        Path path3 = Paths.get("d:\\", "nio");
        Path path4 = Paths.get("nioo\\hi.txt");
        path3 = path3.resolve(path4);
        System.out.println(path3);

//		File toFile(): 将Path转化为File类的对象
        File file = path1.toFile();//Path--->File的转换

        Path newPath = file.toPath();//File--->Path的转换

    }


}

网络编程

在这里插入图片描述

网络通信协议 在这里插入图片描述

通信要素1:IP 和 端口号

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

/**
 * 一、网络编程中有两个主要的问题:
 * 1.如何准确地定位网络上一台或多台主机;定位主机上的特定的应用
 * 2.找到主机后如何可靠高效地进行数据传输
 *
 * 二、网络编程中的两个要素:
 * 1.对应问题一:IP和端口号
 * 2.对应问题二:提供网络通信协议:TCP/IP参考模型(应用层、传输层、网络层、物理+数据链路层)
 *
 *
 * 三、通信要素一:IP和端口号
 *
 * 1. IP:唯一的标识 Internet 上的计算机(通信实体)
 * 2. 在Java中使用InetAddress类代表IP
 * 3. IP分类:IPv4 和 IPv6 ; 万维网 和 局域网
 * 4. 域名:   www.baidu.com   www.mi.com  www.sina.com  www.jd.com
 *            www.vip.com
 * 5. 本地回路地址:127.0.0.1 对应着:localhost
 *
 * 6. 如何实例化InetAddress:两个方法:getByName(String host) 、 getLocalHost()
 *        两个常用方法:getHostName() / getHostAddress()
 *
 * 7. 端口号:正在计算机上运行的进程。
 * 要求:不同的进程有不同的端口号
 * 范围:被规定为一个 16 位的整数 0~65535。
 *
 * 8. 端口号与IP地址的组合得出一个网络套接字:Socket
 *
 * @author acoffee
 * @create 2020-10-21 18:13
 */
public class InetAddressTest {

    public static void main(String[] args) throws UnknownHostException {
        InetAddress inet1 = InetAddress.getByName("192.168.10.14");

        System.out.println(inet1);///192.168.10.14

        InetAddress inet2 = InetAddress.getByName("www.sina.com");
        System.out.println(inet2);//www.sina.com/101.206.202.228

        InetAddress inet3 = InetAddress.getByName("127.0.0.1");
        System.out.println(inet3);

        //获取本地ip
        InetAddress inet4 = InetAddress.getLocalHost();
        System.out.println(inet4);//DESKTOP-F6H0M5U/169.254.230.191

        //getHostName
        System.out.println(inet2.getHostName());//www.sina.com
        //getHostAddress
        System.out.println(inet2.getHostAddress());//101.206.202.225

    }
}

通信要素2:网络协议

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

TCP网络编程

1.客户端发送内容给服务端,服务端将内容打印到控制台上。

package com.acoffee.java;

import org.junit.Test;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @author acoffee
 * @create 2020-10-21 19:22
 */
public class TCPTest1 {

    //客户端
    @Test
    public void client() {
        Socket socket = null;
        OutputStream os = null;
        try {
            //1.创建Socket对象,指明服务器端的ip和端口号
            InetAddress inet = InetAddress.getByName("127.0.0.1");
            socket = new Socket(inet, 8899);

            //2.获取一个输出流,用于输出数据
            os = socket.getOutputStream();

            //3.写出数据的操作
            os.write("我是Frank,你好!".getBytes());

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                //4.资源的关闭
                if (os != null)
                    os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (socket != null)
                    socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    //服务端
    @Test
    public void server(){
        ServerSocket serverSocket = null;
        Socket socket = null;
        InputStream is = null;
        ByteArrayOutputStream baos = null;
        try {
            //1.创建服务器的ServerSocket,指明自己的端口号
            serverSocket = new ServerSocket(8899);

            //2.调用accept()表示接受来自于客户端的socket
            socket = serverSocket.accept();

            //3.获取输入流
            is = socket.getInputStream();

            //不建议下述写法:
            //可能会出现乱码:传递的是中文如果我们将
            //这里传递的字节数设置的太小的的话可能会将其劈成两半
            //从而导致乱码
//        byte[] buffer = new byte[20];
//        int len;
//        while ((len = is.read(buffer)) != -1){
//            String str = new String(buffer, 0, len);
//            System.out.println(str);
//        }

            //在这里我们使用ByteArrayOutputStream()其原理是将
            //它会将我们输入的内容保存在一个数组当中,知道我们的
            //内容写入完毕过后,它才会一次性整体读出然后整体转化为
            // 字符串,从而不会导致乱码

            //4.读入输入流中的数据
            baos = new ByteArrayOutputStream();

            byte[] buffer = new byte[5];
            int len;
            while ((len = is.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
            }

            System.out.println(baos.toString());
            System.out.println("收到了来自于:" + socket.getInetAddress().getHostAddress() + "的数据!");

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                //5.关闭流
                if (baos != null)
                    baos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (is != null)
                    is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (socket != null)
                    socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (serverSocket != null)
                    serverSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }
}

执行结果:在这里插入图片描述

2.客户端发送文件给服务端,服务端将文件保存在本地。

package com.acoffee.java;

import org.junit.Test;

import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @author acoffee
 * @create 2020-10-21 20:01
 */
public class TCPTest2 {

    //这里涉及到的异常需要使用try-catch-finally来处理
    @Test
    public void client() throws IOException {
        //1.造套接字
        Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9090);
        //2.获取输出流
        OutputStream os = socket.getOutputStream();
        //3.获取输入流
        FileInputStream fis = new FileInputStream(new File("1.png"));
        //4.操作细节
        byte[] buffer = new byte[1024];
        int len;
        while ((len = fis.read(buffer)) != -1){
            os.write(buffer,0,len);
        }

        fis.close();
        os.close();
        socket.close();
    }

    @Test
    public void Server() throws IOException {
        ServerSocket ss = new ServerSocket(9090);

        Socket socket = ss.accept();

        InputStream is = socket.getInputStream();

        FileOutputStream fos = new FileOutputStream(new File("123.png"));
        byte[] buffer = new byte[1024];
        int len;
        while ((len = is.read(buffer)) != -1){
            fos.write(buffer,0,len);
        }
        fos.close();
        is.close();
        socket.close();
        ss.close();
    }
}

3.从客户端发送文件给服务端,服务端保存到本地。并返回“发送成功”给 客户端。并关闭相应的连接。

package com.acoffee.java;

import org.junit.Test;

import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @author acoffee
 * @create 2020-10-21 20:01
 */
public class TCPTest2 {

    //这里涉及到的异常需要使用try-catch-finally来处理
    @Test
    public void client() throws IOException {
        //1.造套接字
        Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9090);
        //2.获取输出流
        OutputStream os = socket.getOutputStream();
        //3.获取输入流
        FileInputStream fis = new FileInputStream(new File("1.png"));
        //4.操作细节
        byte[] buffer = new byte[1024];
        int len;
        while ((len = fis.read(buffer)) != -1){
            os.write(buffer,0,len);
        }

        //这里我们在客户端传输完毕过后,我们关闭数据的输出
        //如果不关闭,服务器端我知道我们到底传媒传完,就会
        //一直等待
        socket.shutdownOutput();

        //5.接受来自于服务器的数据,并显示到控制台上
        InputStream is = socket.getInputStream();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        byte[] buffer1 = new byte[20];
        int len1;
        while ((len1 = is.read(buffer1)) != -1){
            baos.write(buffer1,0,len1);
        }


        System.out.println(baos.toString());

        fis.close();
        os.close();
        socket.close();
        baos.close();
    }

    @Test
    public void Server() throws IOException {
        ServerSocket ss = new ServerSocket(9090);

        Socket socket = ss.accept();

        InputStream is = socket.getInputStream();

        FileOutputStream fos = new FileOutputStream(new File("12.png"));

        byte[] buffer = new byte[1024];
        int len;
        while ((len = is.read(buffer)) != -1){
            fos.write(buffer,0,len);
        }

        System.out.println("图片传输完成");

        //服务器端给与客户端反馈
        OutputStream os = socket.getOutputStream();
        os.write("你好!I'm coco!".getBytes());


        fos.close();
        is.close();
        socket.close();
        ss.close();
        os.close();
    }
}

执行结果:
在这里插入图片描述
在这里插入图片描述

UDP网络编程

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.acoffee.java;

import org.junit.Test;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

/**
 * @author acoffee
 * @create 2020-10-21 21:15
 */
public class UDPTest {
    @Test
    public void sender() throws IOException {
        DatagramSocket socket = new DatagramSocket();

        String str = "我是UDP方式发送的导弹";
        byte[] data = str.getBytes();
        InetAddress inet = InetAddress.getLocalHost();
        DatagramPacket packet = new DatagramPacket(data,0,data.length,inet,9090);

        socket.send(packet);

        socket.close();


    }

    @Test
    public void receiver() throws IOException {

        DatagramSocket socket = new DatagramSocket(9090);

        byte[] buffer = new byte[100];
        DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);

        socket.receive(packet);

        System.out.println(new String(packet.getData(), 0, packet.getLength()));

        socket.close();

    }
}

URL编程

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
URLTest类:

package com.atguigu.java1;

import java.net.MalformedURLException;
import java.net.URL;

/**
 * URL网络编程
 * 1.URL:统一资源定位符,对应着互联网的某一资源地址
 * 2.格式:
 *  http://localhost:8080/examples/beauty.jpg?username=Tom
 *  协议   主机名    端口号  资源地址           参数列表
 *
 * @author acoffee
 * @create 2020 下午 4:47
 */
public class URLTest {

    public static void main(String[] args) {

        try {

            URL url = new URL("http://localhost:8080/examples/beauty.jpg?username=Tom");

//            public String getProtocol(  )     获取该URL的协议名
            System.out.println(url.getProtocol());
//            public String getHost(  )           获取该URL的主机名
            System.out.println(url.getHost());
//            public String getPort(  )            获取该URL的端口号
            System.out.println(url.getPort());
//            public String getPath(  )           获取该URL的文件路径
            System.out.println(url.getPath());
//            public String getFile(  )             获取该URL的文件名
            System.out.println(url.getFile());
//            public String getQuery(   )        获取该URL的查询名
            System.out.println(url.getQuery());




        } catch (MalformedURLException e) {
            e.printStackTrace();
        }

    }


}

URLTest1类:

package com.atguigu.java1;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * @author acoffee
 * @create 2020 下午 4:54
 */
public class URLTest1 {

    public static void main(String[] args) {

        HttpURLConnection urlConnection = null;
        InputStream is = null;
        FileOutputStream fos = null;
        try {
            URL url = new URL("http://localhost:8080/examples/beauty.jpg");

            urlConnection = (HttpURLConnection) url.openConnection();

            urlConnection.connect();

            is = urlConnection.getInputStream();
            fos = new FileOutputStream("day10\\beauty3.jpg");

            byte[] buffer = new byte[1024];
            int len;
            while((len = is.read(buffer)) != -1){
                fos.write(buffer,0,len);
            }

            System.out.println("下载完成");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭资源
            if(is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(fos != null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(urlConnection != null){
                urlConnection.disconnect();
            }
        }
    }
}

在这里插入图片描述
在这里插入图片描述

每日一练:

1. 一个IP对应着哪个类的一个对象?InetAddress
实例化这个类的两种方式是?

InetAddress.getByName(String host);
InetAddress.getLocalHost();//获取本地ip
两个常用的方法是?
getHostName();
getHostAddress();

2. 传输层的TCP协议和UDP协议的主要区别是?

TCP:可靠的数据传输(三次握手);进行大数据量的传输;效率低

UDP:不可靠;以数据报形式发送,数据报限定为64k;效率高

3. 什么是URL,你能写一个URL吗?

URL:统一资源定位符
URL url = new
URL(“http://192.168.14.100:8080/examples/hello.txt?username=Tom”);

4. 谈谈你对对象序列化机制的理解

序列化过程:允许把内存中的Java对象转换成平台无关的二进制流,从 而允许把这种二进制流持久地保存在磁盘上,通过网络将这种二进制流传 输到另一个网络节点。

反序列化过程:当其它程序获取了这种二进制流,就可以恢复成原 来的Java对象

5. 对象要想实现序列化,需要满足哪几个条件

①. 实现接口:Serializable 标识接口
②. 对象所在的类提供常量:序列版本号
③. 要求对象的属性也必须是可序列化的。(基本数据类型、String:本身就已经是可序列化的。)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值