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(); } } } }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 }随着 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.如何准确地定位网络上一台或多台主机;定位主机上的特定的应用 * 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 } }
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(); } }执行结果:
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(); } }
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:本身就已经是可序列化的。)