学习中关于IO与WEB基础方面的笔记
只是个人自学时的笔记
一、IO基础流
-
一:流的分类:
-
1.方向:输入流,输出流
-
2.角色:文件流(节点),处理流
-
3.操作单位:字节流byte[1],字符流char[2]
-
二:体系结构
-
抽象基类: 节点流(文件流) 缓冲流(处理流的一种)
-
InputStream(字节流) FileInputStream BufferedInputStream
-
OutputStream(字节流) FileOutputStream BufferedOutputStream
-
write(字符流) FileWrite BufferedWriter
-
read(字符流) FileRead BufferedReader
-
三:基础方法
-
- File文件
-
方法:
-
//获取绝对路径:getAbsolutePath //public getPath() :获取路径 //public getName():获取名称 //public String getParent() :获取上层文件目录路径,无,返回null //public Long Length() :获取文件长度:字节数,不能获取目录长度 //public Long LastModified() :获取最后一次的修改时间:毫秒 如下两个方法适用于文件目录: //public String[] list() :获取指定目录下的所有文件或者文件目录的名称数组 //public File[] ListFiles() :获取指定目录下的所有文件或者文件目录的file数组
-
//public boolean renameTo(File dest);把文件重命名为指定的文件路径
-
比如:file1.renameTo(File2)为例
-
boolean is File:是否是文件
-
boolean is Directory:是否是文件目录
-
boolean exists:是否存在
-
boolean canread:是否能读
-
boolean canWrite:是否能写
-
boolean isHidden:是否隐藏
-
创建功能:
-
public boolean creatNewFile:创建文件,若文件存在,返回false
-
public boolean mkdir:创建文件目录
-
public boolean mkdirs:创建文件目录,如果上层目录不存在,一起创建
-
删除
-
public boolean delete:删除文件或文件夹
-
注意:java中的删除不走回收站
-
1.read:读取硬盘中的一个字符
-
2.建议使用try - catch -finally 进行,将close放入finally进行必要关闭,且最好设置条件防止文件读取操作失败出现的空指针异常
-
3.读入的文件一定要存在,否则出现FileNotFoundException
*字节流: -
使用字节流:复制时中文占三个字节,如果字节超过了一次性读取数组的长度,就会出现乱码(即将一个汉字分隔开)
-
使用字符流:不会出现以上问题
-
对于文本文件,使用字符流处理:txt,java,c,cpp
-
非文本文件,使用字节流处理:如果单纯使用字节流复制,也可以使用字节流。只是不可以在控制台方面读取数据
-
定义数组确定每次复制长度时,
-
若数组太大则占用过多内存,若数组太小则速度变慢
-
其他事项/*
-
IO基于流
-
NIO基于缓冲区:可以更加高效的进行读写,但程序书写繁琐
-
NIO2对NIO进行了扩展
-
内部使用buffer结构
-
NIO.channels.Channel
-
FileChannel:处理文件
-
NIO2:
-
Path,Files,paths
-
Path:可以看出file的升级版本,弥补了file返回失败且不会提供异常信息的不足,
-
Files:
-
paths:
-
jar包:提供额外的api
-
导入方法:右键-新建directory-复制jar包-Add as Library
-
*/
二、处理流:
一:缓冲流:处理流之一
*1.基本概念
- 用于节省文件读取的效率
- BufferInputStream BufferReader
- BufferOutPutStream BufferWriter
- 2.作用:提高流的读取,写入速度
- 快过字节流的速度,内部含有8192个字节的缓冲区,可以进行快速输出
- 处理流内部有flush方法,在每次调用时刷新缓存区。
二:转换流
处理流之二: - 1.转换流(在字符流体系下,也是处理流):
- InputStreamReader:将输入字节的输入流转换字符的输入流.
- :使用InputStream读取字符流文件本会出现乱码,将其套用在InputStreamReader中就可以避免
- OutputStreamWriter:将一个字符的输出流转换为字节的输出流
- :将字节文件使用字符方式存储,
-
- 作用:提供字节流与字符流之间的转换
-
- 解码: 字节,字节数组---->字符数组,字符串
- 编码: 字符数组,字符串------>字节数组,字节
三、其他特殊流
一:标准输入输出流
* 输入输出流:
* System.out:输出到显示器:方法:①print ②println 是PrintStream类型 ,即FileOutStream的子类
* System.in:从键盘读取数据,是InputStream类型
二:打印流
*
* :将基本类型的数据格式转化为字符串输出
* 不会抛异常
* 自动flush
*
* printStream
* printWrite
* 提供了一系列重载的print和println方法
* System.out.print():标准方法
三:处理流之三
/*
* 处理流:数据流
* Data inputStream 和 DataOutputStream
* 作用:操作基本数据类型和String,读取或写出基本数据类型的变量或字符串
* inputStream
* boolean readBoolean()
* byte readByte()
*
* outputStream
* boolean writeBoolean()
* byte writeByte()
*注意:读取时每次读取的数据类型要和写入时保持一致
* /
四:对象流
/
* 可以传输对象或基本类型数据,也可以把对象从数据源中还原回来
*
* 序列化:用ObjectOutputStream类保存基本数据类型或对象的机制
* 反序列化:用ObjectInputStream读取基本数据类型或对象的机制
* 对象序列化机制:将java对象打乱成二进制流,从而将其保存在磁盘等地方,也可以通过网络将其传输到另一个节点。
* 当其他程序获取了这种二进制流,也可以将其转化为java对象
*
*
* java对象可序列化需要满足的要求:
* 1.必须实现两个接口之一 :io.Serializable :Externalizable
* Serializable:标识接口,没有内部方法,凡是实现此接口的类都是可以实现序列化的
* 2.声明一个为:public static final long serializableVersionUID = 4648979798797977L;的对象
* UID的作用:给对象一个标识,用来识别二进制码的类
* 3.除了当前Person类需要实现serializable接口之外,还需要保证其内部所有属性都可以序列化(其他类构成的对象)。
* 默认情况下,基本数据类型都是可序列化的,String也可序列化
*
*
* 补充:不可序列化static 和 transient对象
* transient:表示该属性不可序列化
*
*
* */
五:随机存取文件流
- 1.RandomAccessFile:既可以作为输入流,也可以作为输出流
-
直接继承于java.lang.Object类,实现了DataInput 和 DataOutput接口
- 2.RandomAccessFile
- 需要制定mode参数,该参数指定访问模式:
1.r:以只读方式打开
2.rw:可以读入也可以写出
3.rwd:同步文件内容的更新
4.rwd:同步文件内容和元数据的更新 - 3.输出时对文件内容的覆盖
- 作为输出流时,如果写出到的文件不存在,则在执行过程中自动创建
- 如果写出到的文件存在,则会对原有文件内容进行覆盖,且从头开始
四、网络编程基本概念
一:要想进行网络通信,需要解决的两个问题
* 1.如何定位网络上一台或多台主机,定位主机上特定的应用
* 2.找到主机后如何可靠高效的进行数据传输
*
*
* 两个要素:
* 1.对应问题一:ip和端口号
* 2.对应问题二:提供网络通信协议(TCP\IP参考模型):应用层,传输层,网络层,物理+数据链路层
二: 网络通信又称为socket编程
-
网络编程主要问题:
-
1.如何定位网络上一台或多台主机,定位主机上特定的应用
-
2.找到主机后如何可靠高效的进行数据传输
-
规则:
-
1.网络通信协议
-
2.TCO/IP参考模型(或TCP/IP协议):事实上的国际标准
-
将网络划分成四层:上层与下层可以进行数据传输
-
1.应用层:HTTP.FTP.telnet,DNS
-
2.传输层:TCP,UDP
-
3.网络层:IPI,CMP,ARP
-
4.物理+数据链路层:Link
-
要素概括:
-
1.ip和端口号
-
ip:唯一的表示internet上的计算机(通信实体)
-
本地回环地址(hostAddress)
-
InetAddress:类,代表IP地址
-
分类方式一:
-
ipv6:128位(16字节):8个无符号整数,没个整数用四个十六进制表示,数之间用冒号分开
-
ipv4:以点分十进制表示,已经用尽
-
分类方式二:
-
公网地址(万维网使用):
-
私有地址(局域网使用):192.168开头的是私有地址
-
域名:www.baidu.com
-
DNS:域名解析服务器,将域名解析为IP地址
-
本地回路地址:127.0.0.1 :对应着localhost(本地的主机)
-
java中使用inetAddress类代表IP
-
实例化inetAddress:byname方法获取确定的ip
-
端口号:标识正在计算机上运行的进程
-
要求:
-
不同的进程有不同的端口号,端口号不可重复
-
被规定为一个16位的整数0-65535
-
端口分类:
-
公认端口:0-1023
-
注册端口:1024-49151:分配给用户进程或应用程序:如comtat:8080
-
动态/私有端口:49152-65535
-
端口号和ip地址组合在一起形成一个网络套接字:socket
-
要素2:网络通信协议:对速率,传输代码,传输控制步骤,出错控制等制定标准
五、TCP网络编程
TCP网络编程:
* 1.三次握手:目的,建立可靠连接
* 2.四次挥手:确定连接断开
简单的客户端与服务端交互实例
//客户端
@Test
public void Test1() {
ByteArrayOutputStream bos = null;
Socket socket = null;
OutputStream outputStream = null;
FileInputStream fis = null;
try {
InetAddress byName = InetAddress.getByName("127.0.0.1");
socket = new Socket(byName, 9090);
outputStream = socket.getOutputStream();
//创建处理流包装需要传输的文件
fis = new FileInputStream(new File("复制体.jpg"));
byte[] by = new byte[1024];
int len;
while ((len = fis.read(by))!=-1){
outputStream.write(by,0,len);
}
//方法:关闭数据输出
socket.shutdownOutput();
//接收来自服务器端的数据
//
System.out.println("图片传输开始");
InputStream is = socket.getInputStream();
OutputStream os = new ByteArrayOutputStream();
byte[] bo = new byte[1024];
int leng;
while ((leng = is.read(bo))!=-1){
os.write(bo,0,leng);
}
// socket.shutdownInput();
System.out.println(os.toString());
//说明传输失败
//传输失败的原因:read是一种阻塞式的方法,即没有明确的结束表示,就会始终进行下去
System.out.println("图片传输完成");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
try {if (bos!=null)
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//服务器端
@Test
public void Test2(){
ServerSocket ss = null;
Socket socket = null;
InputStream is = null;
FileOutputStream fos = null;
OutputStream outputStream = null;
try {
//指明端口号
ss = new ServerSocket(9090);
//表明可以接收socket的数据
socket = ss.accept();
is = socket.getInputStream();
fos = new FileOutputStream(new File("复制体20.jpg"));
byte[] by = new byte[1024];
int len;
while ((len = is.read(by))!=-1){
fos.write(by,0,len);
}
//服务器端给予客户端反馈:接收来自服务器端的数据,并显示到控制台上
OutputStream os = socket.getOutputStream();
os.write("发送成功".getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
六、UDP网络编程
UDP:不可控的连接(不确定是否能安全到达目的地,且不确定什么时候可以到达)
实例://发送端
@Test
public void Test() throws IOException {
DatagramSocket socket = new DatagramSocket();
//构造器:空参
String str = "UDP发送";
byte[] by = str.getBytes();
//数据封装在DatagramPacket中
InetAddress inet =InetAddress.getLocalHost();
DatagramPacket dgsk = new DatagramPacket(by,0,by.length,inet,8899);
socket.send(dgsk);
socket.close();
}
//接收端
@Test
public void Test2() throws IOException{
//接收端需要指明自己的端口号
DatagramSocket dgs = new DatagramSocket(8899);
//new DatagramPacket
byte[] buffer = new byte[100];
DatagramPacket datagramPacket = new DatagramPacket(buffer,0,buffer.length);
//将packet中的数据封装到dgs中,使用receive方法
dgs.receive(datagramPacket);
//获取packet中的数据
System.out.println(new String(datagramPacket.getData(), 0, datagramPacket.getLength()));
dgs.close();
}
七、URL网络编程
/*
* 1.URL:统一资源定位符,表示internet上某一资源的地址
*
* 2.URL包含五个部分:
* 传输协议-主机名ip-端口号-文件名-参数列表/片段名
* 协议:http/https ip: 端口号: 文件名: 参数列表:?之后即为参数列表
* 格式:https://i.csdn.net/#/user-center/profile?spm=1001.2100.3001.5111
*
*
* */
一个简单的实例
public static void main(String[] args)throws IOException {
URL url = new URL("https://i.csdn.net/#/user-center/profile?spm=1001.2100.3001.5111");
//下载对应服务器端资源
//1.运行服务器
//2.获取服务器的连接:方法,url.openConnection,将其变为协议对应类型的
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
//使用协议对象获取连接,此时才真正获取了连接
urlConnection.connect();
//拿到输入流
InputStream is = urlConnection.getInputStream();
FileOutputStream fos = new FileOutputStream("beauty3.jpg");
byte[] by = new byte[1024];
int len;
while ((len = is.read(by))!=-1){
fos.write(by,0,len);
}
System.out.println("下载完成");
//关闭资源
is.close();
fos.close();
//disconnect:断开连接
urlConnection.disconnect();
}