gpt4 book ai didi

通过 Sockets 的 Java 文件传输修剪最后字节

转载 作者:太空宇宙 更新时间:2023-11-04 11:25:02 24 4
gpt4 key购买 nike

我一直在尝试创建一个具有文件传输功能的 Messenger,但最后总是有太多空字符。任何时候我使用文件长度来剥离它们,由于某种原因,更多的文件被剥离,它变得一团糟。我没有使用任何 Java 7 或更高版本的元素,因为我希望它与 Java 6 和 Windows 98(奶奶的 PC)兼容。

我还在文件中添加了很多随机空字符,我不知道如何避免这种情况

这是我的代码:传输

package com.androdome.lunacoffee.management;

import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

import com.androdome.lunacoffee.ErrorScreen;
import com.androdome.lunacoffee.SendScreen;

public class FileTransmitter implements Runnable{
String adds;
FileInputStream message;
int filecut = 4096;
byte[] fileName;
long fileSize;
SendScreen send;
public FileTransmitter(String address, FileInputStream msg, byte[] fnme, SendScreen snd, long l) {
adds = address;
send = snd;
message = msg;
fileName = fnme;
fileSize = l;
}




public void run()
{
try {
InetAddress add = InetAddress.getByName(adds);
Socket sock = new Socket(add, 11001);
DataOutputStream da = new DataOutputStream(sock.getOutputStream());
PrintWriter output = new PrintWriter(da);
da.write(fileName);


da.writeLong(message.getChannel().size());

byte[] filebuffer = new byte[filecut];
int g = 0;
int back = 0;
while((g = message.read(filebuffer)) != -1)
{
if(g != filecut && g > 0)
{
back = g;
}
da.write(filebuffer);
filebuffer = new byte[filecut];
}
da.writeInt(back);
System.out.print(back);

output.flush();
output.close();
send.incrementSent();
} catch (UnknownHostException e) {
send.incrementError();
// TODO Auto-generated catch block
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
new ErrorScreen("Unable to send file", "Your file was not able to send because the host \"" + adds + "\" was not availible!", sw.toString());
pw.close();
try {
sw.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}

} catch (IOException e) {
send.incrementError();
// TODO Auto-generated catch block
new ErrorScreen("Unable to send file", "Your file was not able to send due to a bad output stream!", e.getMessage());
}
}

}

收到:

package com.androdome.lunacoffee.management;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;

import com.androdome.lunacoffee.ErrorScreen;
import com.androdome.lunacoffee.FileScreen;
import com.androdome.lunacoffee.Main;

public class FileReciever implements Runnable {
int bufferSize = 4096;
int headerSize = 32;
byte[] filebuffer = new byte[bufferSize];
byte[] fileheader = new byte[headerSize];
Main main;
File downloadfile = new File("tmp");
File transferFile = new File("dnl.ldf");
public FileReciever(Main mn)
{
main = mn;
}


static byte[] trim(byte[] bytes)
{
int i = bytes.length - 1;
while (i >= 0 && bytes[i] == 0)
{
--i;
}

return Arrays.copyOf(bytes, i + 1);
}

public void run() {


try {
ServerSocket recieveSocket = new ServerSocket(11001);
while (this != null) {
try{
downloadfile.createNewFile();
Socket connectionSocket = recieveSocket.accept();
DataInputStream reader = new DataInputStream(connectionSocket.getInputStream());
reader.read(fileheader);
long fileSize = reader.readLong();
System.out.println(bufferSize);
filebuffer = new byte[bufferSize];

String fileName = new String(fileheader);
fileheader = new byte[headerSize];
FileOutputStream fw = new FileOutputStream(downloadfile);
while(reader.read(filebuffer) != -1)
{
fw.write(filebuffer);
filebuffer = new byte[bufferSize];
}
//reader.readInt();
reader.close();
fw.close();
//RandomAccessFile file = new RandomAccessFile(downloadfile, "Rwd");
//file.setLength(fileSize); // Strip off the last _byte_, not the last character
//file.close();

connectionSocket.close();
FileScreen fs = new FileScreen(downloadfile, fileName, connectionSocket.getInetAddress().getHostName());
fs.setVisible(true);
fs.setLocationRelativeTo(null);
}
catch(Exception ex)
{}
}
} catch (IOException e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
new ErrorScreen("Unable to start the File Recieve Thread", "Luna Messenger may already be running, or another program is using port 11001. Please close any program running on port 11001.", sw.toString());
pw.close();
try {
sw.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}

}

最佳答案

在上面的代码中,我认为它犯了以下错误。首先,您应该添加一个数字来指示文件名的长度。如下所示:

da.writeInt(fileName.length);  //the added code
da.write(fileName);

FileReciever上,接收代码为:

int fileNameLength = reader.readInt();
fileheader=new byte[fileNameLength];
read(reader,fileheader,0,fileNameLength);

read 方法可以从输入流中读取最多 length 个字节到字节数组中,直到流结束。

public static int read(InputStream in, byte[] b, int off, int len) throws IOException {
if (len < 0) {
throw new IndexOutOfBoundsException("len is negative");
}
int total = 0;
while (total < len) {
int result = in.read(b, off + total, len - total);
if (result == -1) {
break;
}
total += result;
}
return total;
}

第二,FileTransmitter将文件日期转换为FileReciever是不正确的,并且不应在末尾添加数字。正确的做法是将文件数据写入FileTransmitter中的套接字输出流,并且不执行任何其他操作。如下所示:

while((g = message.read(filebuffer)) != -1)
{
da.write(filebuffer,0,g);
}

另一方面,应该读取多少字节取决于您之前从套接字 oupustream 读取字节到 filebuffer 中时从套接字输入流读取的字节长度。接收器代码:

int readLength;
int sumLength=0;
while((readLength=reader.read(filebuffer,0,(int)(fileSize-sumLength>filebuffer.length?filebuffer.length:fileSize-sumLength))) != -1){
sumLength+=readLength;
fw.write(filebuffer,0,readLength);
if(sumLength==fileSize){
break;
}
}

关于通过 Sockets 的 Java 文件传输修剪最后字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44474260/

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