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
有几个优点:
-
简化代码: 不需要手动创建缓冲区或字节数组,简化了代码结构。
-
性能优化:
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
FileOutputStream
和 OutputStreamWriter
是 Java 中用于处理文件输出的两个不同的类。它们之间的主要区别在于处理的数据类型和提供的功能。以下是它们的一些主要区别:
1. FileOutputStream
:
- 数据类型:
FileOutputStream
是字节流,用于写入字节数据。 - 功能: 它提供了直接将字节写入文件的能力,适用于处理二进制数据,如图像、音频等。
- 编码: 不关心字符编码,它操作的是字节而不是字符。
所以在这里,我们的client不仅仅可以传输txt文件,任何类型的文件都可以传输,只要server接受这个文件时,存储方式不发生变化就行。比如传.class文件,接受时也是.class文件。
可以实现这种传输的原因是 FileOutputStream
是字节流,对于这段字节,只要你编码的方式(txt按txt文件编码格式读取,class按class文件编码格式读取)是一样的,就永远可以读出正确的内容。
2. OutputStreamWriter
:
- 数据类型:
OutputStreamWriter
是字符流,用于写入字符数据。 - 功能: 它是字节流到字符流的桥梁,将字节转换为字符并将字符写入文件。提供了字符编码的支持。
- 编码: 可以指定字符编码,适用于处理文本数据,支持字符集的设置,例如UTF-8、ISO-8859-1等。
而对于字符,如果编码格式不一样,可能会出现乱码。