socket从客户端向主机传输一个文件

发布时间:2024年01月09日

client

FileInputStream 是 Java 中用于从文件中读取字节流的类,它属于字节流的一部分。它主要用于读取原始的字节数据,例如图像、音频、文本文件等。FileInputStream 继承自 InputStream 类。

//将需要读取的文件变成可输出的流
            FileInputStream fileInputStream=new FileInputStream("text.txt");

使用 FileInputStream 时,您可以使用 read 方法逐个字节地读取文件内容,或使用 read(byte[] b) 方法一次读取多个字节到字节数组中。

首先,将需要读取的文件放入一个输入流a中,然后我们创建一个数组b,将输入流a中的数据写入数组b,然后创建输出流c,用输出流c输出数组b(也就是输出a)

public class Client {
    public static void main(String[] args) {
        try(Socket socket=new Socket("localhost",8080)){
            //将需要读取的文件变成可输出的流
            FileInputStream fileInputStream=new FileInputStream("text.txt");
            //把socket的输出流和io的输出流绑定,使得io操作更方便
            OutputStream stream=socket.getOutputStream();
            //从需要读取的文件读取内容后,需要暂时存放在这个数组里
            byte[] bytes=new byte[1024];
            int i;
            //将需要读取的文件的可输出流写入数组,i表示写入的数据数量,当i==-1的时候表示什么都没有读取到
            while((i=fileInputStream.read(bytes))!=-1){
                //从数组里读取内容,写入io输出流中(也就是写入了socket的输出流)
                //0表示从0开始读取
                //i表示一次读取i位
                stream.write(bytes,0,1);
            }
            stream.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

当然,我们也可以省略中间的那个数组b ,将需要发送的文件转化为输入流a后,直接发送给输出流c:

import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

public class Client {
    public static void main(String[] args) {
        try (Socket socket = new Socket("localhost", 8080);
             FileInputStream fileInputStream = new FileInputStream("text.txt");
             OutputStream outputStream = socket.getOutputStream()) {

            // 使用 transferTo 将文件内容直接传输到输出流
            long bytesTransferred = fileInputStream.transferTo(outputStream);

            // 刷新输出流,确保所有数据都被发送到服务器
            outputStream.flush();

            System.out.println("Transferred " + bytesTransferred + " bytes.");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

使用 transferTo 有几个优点:

  1. 简化代码: 不需要手动创建缓冲区或字节数组,简化了代码结构。

  2. 性能优化: transferTo 方法的实现可能会利用底层系统的优化,例如零拷贝(zero-copy)技术,提高了大数据传输的性能。

server

?这里使用了transferTo方法

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    public static void main(String args[]) {
        try (ServerSocket server = new ServerSocket(8080)) {
            // 等待客户端连接
            Socket socket = server.accept();
            
            // 获取与客户端连接的输入流
            InputStream inStream = socket.getInputStream();

            // 创建输出流,用于写入接收到的数据到本地文件
            try (FileOutputStream outStream = new FileOutputStream("C:\\Users\\86136\\projects\\IdeaProjects\\javaWeb\\src\\socket2文件传输\\text2.txt")) {
                // 使用 transferTo 方法直接从输入流传输数据到输出流
                inStream.transferTo(outStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

I/O4

FileOutputStreamOutputStreamWriter 是 Java 中用于处理文件输出的两个不同的类。它们之间的主要区别在于处理的数据类型和提供的功能。以下是它们的一些主要区别:

1. FileOutputStream:

  • 数据类型: FileOutputStream 是字节流,用于写入字节数据。
  • 功能: 它提供了直接将字节写入文件的能力,适用于处理二进制数据,如图像、音频等。
  • 编码: 不关心字符编码,它操作的是字节而不是字符。

所以在这里,我们的client不仅仅可以传输txt文件,任何类型的文件都可以传输,只要server接受这个文件时,存储方式不发生变化就行。比如传.class文件,接受时也是.class文件。

可以实现这种传输的原因是?FileOutputStream 是字节流,对于这段字节,只要你编码的方式(txt按txt文件编码格式读取,class按class文件编码格式读取)是一样的,就永远可以读出正确的内容。

2. OutputStreamWriter:

  • 数据类型: OutputStreamWriter 是字符流,用于写入字符数据。
  • 功能: 它是字节流到字符流的桥梁,将字节转换为字符并将字符写入文件。提供了字符编码的支持。
  • 编码: 可以指定字符编码,适用于处理文本数据,支持字符集的设置,例如UTF-8、ISO-8859-1等。

而对于字符,如果编码格式不一样,可能会出现乱码。?

文章来源:https://blog.csdn.net/qq_52315213/article/details/135410485
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。