文章目录
每日一考和复习
每日一考
- 说明流的三种分类方式
1.流向:输入流、输出流
2.数据单位:字节流、字符流
3.流的角色:节点流、处理流
- 写出4个IO流中的抽象基类,4个文件流,4个缓冲流
1.InputStream
OutputStream
Writer
Reader
2.FileInputStream
FileOutputStream
FileWriter
FileReader
3.BufferedInputStream
BufferedOutputStream
BufferedWriter
BufferedReader
- 字节流与字符流的区别与使用情境
1.字节流一般用于传输文本文件
2.字符流一般用于传输文本文件
- 使用缓冲流实现a.jpg文件复制为b.jpg文件的操作
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
File file1 = new File("a.jpg");
File file2 = new File("b.jpg");
FileInputStream fis = new FileInputStream(file1);
FileOutputStream fos = new FileOutputStream(file2);
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos);
byte[] buffer = new byte[1024];
int len;
while ((len = bis.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 转换流是哪两个类,分别的作用是什么?请分别创建两个类的对象
InputStreamWriter:将输入的字节流转换为输入的字符流,解码
InputStreamReader isr = new InputStreamReader(new FileInputStream(“a.txt”),”utf-8”);
OutputStreamReader:将输出的字符流转换为输出的字节流,编码
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(“b.txt”),”gbk”);
复习
day26的学习内容
IO流(接day26)
对象流
ObjectInputStream
ObjectOutputStream
-
作用:用于存储和读取基本数据类型数据或对象的处理流。它的强大之处就是可以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来;要求对象是可序列化的
-
序列化机制:
对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点;当其它程序获取了这种二进制流,就可以恢复成原来的Java对象 -
要想一个java对象是可序列化的,需要满足以下要求
1.需要实现接口:Serializable
2.当前类提供一个全局常量:serialVersionUID
3.除了当前Person类需要实现Serializable接口之外,还必须保证其内部所有属性也必须是可序列化的。
(默认情况下,基本数据类型可序列化)
ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量
序列化过程:将内存中的java对象保存到磁盘中或通过网络传输出去
使用ObjectOutputStream
实现
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream("obj.txt"));
oos.writeObject(new String("我爱你三千遍"));
oos.flush();//刷新操作
oos.writeObject(new Person("姓名", 23));
oos.flush();
oos.writeObject(new Person("test", 23, 1001, new Account(5000)));
oos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (oos != null) {
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
反序列化:将磁盘文件中的对象还原为内存中的一个java对象
使用ObjectInputStream
来实现
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream("obj.txt"));
Object obj = ois.readObject();
String str = (String) obj;
Person p = (Person) ois.readObject();
Person p1 = (Person) ois.readObject();
System.out.println(str);
System.out.println(p);
System.out.println(p1);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
if (ois != null) {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
RandomAccessFile
-
RandomAccessFile直接继承于java.lang.Object类,实现了DataInput和DataOutput接口
-
RandomAccessFile既可以作为一个输入流,又可以作为一个输出流
-
如果RandomAccessFile作为输出流时,写出到的文件如果不存在,则在执行过程中自动创建
如果写出到的文件存在,则会对原有文件内容进行覆盖。(默认情况下,从头覆盖,也可以设置开始的位置) -
可以通过相关的操作,实现RandomAccessFile“插入”数据的效果
RandomAccessFile raf1 = null;
RandomAccessFile raf2 = null;
try {
raf1 = new RandomAccessFile(new File("test.jpg"), "r");// 可读
raf2 = new RandomAccessFile(new File("test1.jpg"), "rw");// 可读可写
byte[] buffer = new byte[1024];
int len;
while ((len = raf1.read(buffer)) != -1) {
raf2.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (raf1 != null) {
try {
raf1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (raf2 != null) {
try {
raf2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用RandomAccessFile实现数据的插入效果
RandomAccessFile raf1 = null;
try {
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));
}
//调回指针,写入插入的数据
raf1.seek(3);
raf1.write("aaa".getBytes());
//将StringBuilder中的数据写入到文件中
raf1.write(builder.toString().getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
if(raf1 != null) {
try {
raf1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
网络编程
网络编程概述
- 网络编程的目的:
直接或间接地通过网络协议与其它计算机实现数据交换,进行通讯 - 网络编程中有两个主要的问题:
- 如何准确地定位网络上一台或多台主机;定位主机上的特定的应用
- 找到主机后如何可靠高效地进行数据传输
网络通信要素概述
- 通信双方地址
IP & 端口号 - 一定的规则
- OSI参考模型:模型过于理想化,未能在因特网上进行广泛推广
- TCP/IP参考模型(或TCP/IP协议):事实上的国际标准
通信要素1:IP和端口号
-
IP:唯一的标识 Internet 上的计算机(通信实体)
-
在Java中使用InetAddress类代表IP
-
IP分类:IPv4 和 IPv6 ;万维网 和 局域网
-
域名: www.baidu.com/ www.mi.com/ www.sina.com/ www.jd.com/ www.vip.com
-
本地回路地址:127.0.0.1 对应着:localhost
-
如何实例化InetAddress:两个方法:
getByName(String host)
、getLocalHost()
两个常用方法:getHostName()
/getHostAddress()
-
端口号:正在计算机上运行的进程
要求:不同的进程有不同的端口号
范围:被规定为一个 16 位的整数 0~65535 -
端口号与IP地址的组合得出一个网络套接字:Socket
通信要素2:网络协议
- 网络通信协议
计算机网络中实现通信必须有一些约定,即通信协议,对速率、传输代码、代码结构、传输控制步骤、出错控制等制定标准 - 通信协议分层的思想
在制定协议时,把复杂成份分解成一些简单的成份,再将它们复合起来。最常用的复合方式是层次方式,即同层间可以通信、上一层可以调用下一层,而与再下一层不发生关系。各层互不影响,利于系统的开发和扩展 - 传输层协议中有两个非常重要的协议
TCP协议 和 UDP协议
TCP网络编程
-
客户端Socket的工作过程包含以下四个基本的步骤:
- 创建 Socket:根据指定服务端的 IP 地址或端口号构造 Socket 类对象。若服务器端响应,则建立客户端到服务器的通信线路。若连接失败,会出现异常
- 打开连接到 Socket 的输入/出流: 使用
getInputStream()
方法获得输入流,使用getOutputStream()
方法获得输出流,进行数据传输 - 按照一定的协议对 Socket 进行读/写操作:通过输入流读取服务器放入线路的信息(但不能读取自己放入线路的信息),通过输出流将信息写入线程
- 关闭 Socket:断开客户端到服务器的连接,释放线路
-
服务器程序的工作过程包含以下四个基本的步骤:
- 调用
ServerSocket(int port)
:创建一个服务器端套接字,并绑定到指定端口上。用于监听客户端的请求 - 调用 accept():监听连接请求,如果客户端请求连接,则接受连接,返回通信套接字对象
- 调用该Socket类对象的
getOutputStream()
和getInputStream ()
:获取输出流和输入流,开始网络数据的发送和接收 - 关闭ServerSocket和Socket对象:客户端访问结束,关闭通信套接字
- 调用
TCP网络编程练习一
客户端发送信息给服务端,服务端将数据显示在控制台上
// 客户端
Socket socket = null;
OutputStream os = null;
try {
//1.创建Socket对象,指明服务器端的ip和端口号
InetAddress inet = InetAddress.getByName("192.168.23.33");
socket = new Socket(inet, 8899);
//2.获取一个输出流,用于输出数据
os = socket.getOutputStream();
//3.写出数据的操作
os.write("你好,我是客户端".getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.资源的关闭
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
ServerSocket ss = null;
Socket socket = null;
InputStream is = null;
ByteArrayOutputStream baos = null;
try {
//1.创建服务器端的ServerSocket,指明自己的端口号
ss = new ServerSocket(8899);
//2.调用accept()表示接收来自于客户端的socket
socket = ss.accept();
//3.获取输入流
is = socket.getInputStream();
//4.读取输入流中的数据
//方式一:不建议这样写,可能会有乱码
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
String str = new String(buffer, 0, len);
System.out.print(str);
}
//方式二
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 {
if (baos != null) {
//5.关闭资源
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (ss != null) {
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
TCP网络编程练习二
客户端发送文件给服务端,服务端将文件保存在本地
// 客户端
Socket socket = null;
OutputStream os = null;
FileInputStream fis = null;
try {
socket = new Socket(InetAddress.getByName("127.0.0.1"), 9090);
os = socket.getOutputStream();
fis = new FileInputStream(new File("beauty.jpg"));
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 服务器端
ServerSocket ss = null;
Socket socket = null;
InputStream is = null;
FileOutputStream fos = null;
try {
ss = new ServerSocket(9090);
socket = ss.accept();
is = socket.getInputStream();
fos = new FileOutputStream(new File("beauty1.jpg"));
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (ss != null) {
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
TCP网络编程练习三
从客户端发送文件给服务端,服务端保存到本地。并返回“发送成功”给客户端
// 客户端
Socket socket = null;
OutputStream os = null;
FileInputStream fis = null;
InputStream is = null;
ByteArrayOutputStream baos = null;
try {
socket = new Socket(InetAddress.getByName("127.0.0.1"), 9090);
os = socket.getOutputStream();
fis = new FileInputStream(new File("beauty.jpg"));
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
//关闭数据的输出
socket.shutdownOutput();
//接收来自于服务器端的数据,并显示到控制台上
is = socket.getInputStream();
baos = new ByteArrayOutputStream();
byte[] buffer1 = new byte[20];
int len1;
while ((len1 = is.read(buffer1)) != -1) {
baos.write(buffer, 0, len1);
}
System.out.println(baos.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
if(fis!=null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(os!=null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(socket!=null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(baos!=null) {
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(is!=null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 服务器端
ServerSocket ss = null;
Socket socket = null;
InputStream is = null;
FileOutputStream fos = null;
OutputStream os = null;
try {
ss = new ServerSocket(9090);
socket = ss.accept();
is = socket.getInputStream();
fos = new FileOutputStream(new File("beauty2.jpg"));
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
System.out.println("图片传输完成");
//服务器端给予客户端反馈
os = socket.getOutputStream();
os.write("照片已收到!".getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (ss != null) {
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
UDP网络编程
// 发送方
DatagramSocket socket = null;
try {
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);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
socket.close();
}
}
// 接收方
DatagramSocket socket = null;
try {
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()));
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
socket.close();
}
}
URL编程
-
URL(Uniform Resource Locator):统一资源定位符,它表示 Internet 上某一资源的地址
-
它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何locate这个资源
-
通过 URL 我们可以访问 Internet 上的各种网络资源,比如最常见的 www,ftp 站点。浏览器通过解析给定的 URL 可以在网络上查找相应的文件或其他资源
-
URL的基本结构由5部分组成:
<传输协议>://<主机名>:<端口号>/<文件名>#片段名?参数列表 -
为了表示URL,java.net 中实现了类 URL,以下是该类的常用方法
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();
}
通过URL编程下载图片
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("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();
}
}