网络和文件流的代码原理,网络流解析,文件流解析

文章探讨了流的概念,特别是在C语言中如何处理不同编码类型的字符存储,以及在Java中如何通过算法转换编码。文件头部的信息,如编码方式和文件大小,对文件处理至关重要。文章还通过示例介绍了如何使用Socket进行TCP文件传输,包括服务器接受客户端文件并保存,以及客户端发送文件的过程。
摘要由CSDN通过智能技术生成

流的概念

基本类型数组,所有的流都是基本类型数组

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模拟实现文件传输

要想实现该操作先创建一个服务端,如下:

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();
    }

}

 紧接着创建客户端进行上传文件

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();
    }
}

注意!!!一定要先将服务端跑起来,只需要改变文件名和路径就可以换文件进行上传

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ADRU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值