gpt4 book ai didi

java - 使用多个 IO 流通过 Java 套接字传输文件

转载 作者:行者123 更新时间:2023-12-01 23:42:46 26 4
gpt4 key购买 nike

最近,我编写了一个简单的客户端服务器程序,用于通过标准 TCP 套接字传输文件。 WiFi channel 的平均吞吐量约为 2.2Mbps。我的问题是:是否可以通过多个数据 IO 流传输一个大文件(例如 5 GB),以便每个流可以以并行方式传输同一文件的多个部分(可以使用不同的线程来实现此目的)?这些文件部分可以在接收端重新组装。我尝试分割一个小文件并通过数据输出流传输它。第一段工作正常,但我不知道如何以选择性的方式读取文件输入流(我也尝试过mark()和reset()方法进行选择性读取,但没有用)

这是我的代码(出于测试目的,我已将输出重定向到 fileoutputstream):

    public static void main(String[] args) {
// TODO Auto-generated method stub
final File myFile=new File("/home/evinish/Documents/Android/testPicture.jpg");
long N=myFile.length();
try {
FileInputStream in=new FileInputStream(myFile);
FileOutputStream f0=new FileOutputStream("/home/evinish/Documents/Android/File1.jpg");
FileOutputStream f1=new FileOutputStream("/home/evinish/Documents/Android/File2.jpg");
FileOutputStream f2=new FileOutputStream("/home/evinish/Documents/Android/File3.jpg");

byte[] buffer=new byte[4096];
int i=1, noofbytes;
long acc=0;
while(acc<=(N/3)) {
noofbytes=in.read(buffer, 0, 4096);
f0.write(buffer, 0, noofbytes);
acc=i*noofbytes;
i++;
}
f0.close();

我得到了文件的第一段(可以将其复制到一个线程中的 DataOutputStream)。谁能建议一下,如何在 N/3 的段中读取文件的剩余部分(N/3 字节之后),以便三个流可以在三个线程中用于并发操作?

以下是在接收端合并文件段的代码:

    package com.mergefilespackage;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class MergeFiles {

/**
* @param args
*/
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
IOCopier.joinFiles(new File("/home/evinish/Documents/Android/File1.jpg"), new File[] {
new File("/home/evinish/Documents/Android/File2.jpg"), new File("/home/evinish/Documents/Android/File3.jpg")});
}
}
class IOCopier {
public static void joinFiles(File destination, File[] sources)
throws IOException {
OutputStream output = null;
try {
output = createAppendableStream(destination);
for (File source : sources) {
appendFile(output, source);
}
} finally {
IOUtils.closeQuietly(output);
}
}

private static BufferedOutputStream createAppendableStream(File destination)
throws FileNotFoundException {
return new BufferedOutputStream(new FileOutputStream(destination, true));
}

private static void appendFile(OutputStream output, File source)
throws IOException {
InputStream input = null;
try {
input = new BufferedInputStream(new FileInputStream(source));
IOUtils.copy(input, output);
} finally {
IOUtils.closeQuietly(input);
}
}
}
class IOUtils {
private static final int BUFFER_SIZE = 1024 * 4;

public static long copy(InputStream input, OutputStream output)
throws IOException {
byte[] buffer = new byte[BUFFER_SIZE];
long count = 0;
int n = 0;
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
count += n;
}
return count;
}

public static void closeQuietly(Closeable output) {
try {
if (output != null) {
output.close();
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}

任何帮助将不胜感激!提前致谢!

最佳答案

使用更多套接字,您无法通过同一链路获得更高的速度。每个套接字发送一定数量的数据包,每个数据包都有一定的大小。当我们将套接字数量加倍时,/秒*套接字的数据包数量减半,然后由于冲突、开销和争用而减少甚至更多。数据包开始碰撞、困惑或出现其他困惑情况。操作系统无法处理丢失 ACK 的困惑情况,并且 WiFi 卡难以以这样的速率进行传输。它也正在失去低级攻击。当数据包丢失时,绝望的 TCP 堆栈会降低传输速率。如果这是由于信号改善而出现的,那么现在由于愚蠢的窗口综合症或另一种形式的 TCP 死锁,它陷入了较低的速度。

任何试图通过更宽的载波频段、MiMo 或多路径获得更高速度的 WiFi 尝试,都已经实现了 yield ,即使是使用一个 socket 。你不能再继续下去了。

现在,等等。我们的 WiFi 速度远远低于,不是吗?当然,我们需要使用缓冲!

确保从套接字的 getInputStream 或 getOutputStream 方法创建 BufferedWriter 和 BufferedReader 对象。然后写入/读取这些缓冲区。您的速度可能会有所提高。

关于java - 使用多个 IO 流通过 Java 套接字传输文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17662228/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com