流的概念
基本类型数组,所有的流都是基本类型数组
C语言中只有六种基本数据类型 char【只有ascll编码,固定只占用1字节】 sort int long float double
比如 我用的utf-32编码的 ,一个编码占用32位,如果用char来存储的话 就需要占用4个char空间,他需要左移来存储,换成编码的时候则需要进行右移操作
例子: 11011110 11011110 11011110 11011110
11011110 00000000 00000000 0000000
11011110 00000000 0000000
11011110 00000000
11011110
在java语言中转换编码用算法进行实现的话大概是类似于以下这种
sort x = arr[i] << 8 + arr[i+1];
char w = ((char)) x;
文件的头部
文件头部通常包含文件的元数据信息,如文件类型、编码方式、文件大小等。编码方式用于指示文件中字符的编码格式,而文件大小指示文件占用的空间大小。这些信息在文件传输和解析时非常重要。
对于文件的编码方式,常见的编码格式包括ASCII、UTF-8、UTF-16等。不同的编码方式使用不同的字符集和编码规则,所以在解析文件时,需要根据文件头部指定的编码方式进行相应的解码操作,以正确地读取和处理文件中的字符数据。
文件大小通常以字节为单位来表示,可以通过读取文件头部中记录的文件大小信息来获取文件的实际大小。这个信息对于文件读取和写入操作非常重要,因为它指示了需要分配的内存空间或网络传输的字节数。
网络流
将网络流的数据读取到内存中的字节数组中,然后根据文件头部的编码方式信息,将字节数组中的数据解码成字符数据。接着,可以根据头部中的文件大小信息来确定需要写入的文件大小,并将解码后的字符数据写入到文件中。
利用socket模拟实现文件传输
要想实现该操作先创建一个服务端,如下:
java
package 文件传输流;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
/**
* tcp服务端
*
* @author 小如
* @date 2023/07/19
*/
public class TCPServer {
public static void main(String[] args) throws IOException {
// 1.创建一个服务端对象(即 ServerSocket),并且向系统要指定的端口号
ServerSocket server = new ServerSocket(8888);
// 2.使用服务端对象的方法 accept 获取请求的客户端对象(即请求连接的 Socket 对象)
Socket socket = server.accept();
// 3.使用 Socket 对象的方法 getInputStream 获取网络字节输入流
InputStream is = socket.getInputStream();
// 4.判断服务端的目标目录路径是否存在,若不存在要创建此目录
File file = new File("D:\\image\\test\\download");
if (!file.exists()) {
file.mkdirs();
}
// 5.创建一个本地字节输出流对象(即 FileOutputStream),构造方法中要绑定写入数据的目标文件路径
FileOutputStream fos = new FileOutputStream(file + File.separator + "1.txt");
// 6.使用网络字节输入流的方法 read 读取客户端发送过来的文件数据
byte[] bytes = new byte[1024];
int i = 0;
while ((i = is.read(bytes)) != -1) {
// 将字节数组中的数据转换成字符串,并打印到控制台
System.out.println(new String(bytes, 0, i));
// 7.使用 FileOutputStream 对象的方法 write 将读取到文件数据写入到服务器本地文件中
fos.write(bytes, 0, i);
}
// 8.使用 Socket 对象的方法 getOutputStream 获取网络字节输出流对象
OutputStream ops = socket.getOutputStream();
// 9.使用网络字节输出流对象的方法 write 给客户端发送一段文字:文件上传成功!
ops.write("文件上传成功!".getBytes());
// 10.释放资源(FileOutputStream、Socket、ServerSocket)
fos.close();
socket.close();
server.close();
}
}
紧接着创建客户端进行上传文件
java
public class TCPClient {
public static void main(String[] args) throws IOException {
// 1. 创建一个本地字节输入流对象(即 `FileInputStream`),构造方法中绑定要读取的数据源
FileInputStream fis = new FileInputStream("D:\\image\\test\\test.txt");
// 2. 创建一个客户端对象(即 Socket 对象),构造方法中绑定 IP 和端口号
Socket socket = new Socket("127.0.0.1", 8888);
// 3. 使用 Socket 对象的方法 getOutputStream,获取网络字节输出流对象
OutputStream os = socket.getOutputStream();
// 4. 使用 FileInputStream 对象的方法 read 读取要上传的文件数据
byte[] bytes = new byte[1024];
int length = 0;
while ((length = fis.read(bytes)) != -1) {
// 5. 使用网络字节输出流对象的方法 write,将读取到的文件数据发送到服务端
os.write(bytes, 0, length); // length 表示获取数组元素的个数
}
// 禁用此套接字的输出流,发送一个终止标记,告知服务端数据的发送已经完成
socket.shutdownOutput();
// 6. 使用 Socket 对象的方法 getInputStream 获取网络字节输入流对象
InputStream is = socket.getInputStream();
// 7. 使用网络字节输入流对象的方法 read 读取服务端回写的数据到指定的字节数组中
length = is.read(bytes);// 读取几个字节,就返回几
// 将字节数组中的数据转换成字符串,并打印到控制台
System.out.println(new String(bytes, 0, length));
// 8. 释放资源(FileInputStream、Socket)
fis.close();
socket.close();
}
}
注意!!!一定要先将服务端跑起来,只需要改变文件名和路径就可以换文件进行上传