gpt4 book ai didi

Java - FTP 程序在传输过程中损坏文件

转载 作者:太空宇宙 更新时间:2023-11-04 15:08:52 26 4
gpt4 key购买 nike

我已经使用套接字制作了一个基本的客户端服务器 FTP 程序,但由于某种原因文件在传输过程中被损坏。在下面的例子中,我将文件从客户端推送到服务器。它几乎可以工作,因为某些文件(例如 .png)可以正常传输和打开,但其他文件(.docx)则不能。我传输的任何文件都具有与我发送的文件不同的 MD5。

客户端代码:

File file = null;
FTPDataBlock transferBlock;
int numBytesRead = 0;
int blockNumber = 1;
int blockSize = 1024;
byte[] block = new byte[blockSize];
fc = new JFileChooser();

// select file to upload
int returnVal = fc.showOpenDialog(Client.this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
file = fc.getSelectedFile();

try {
// get total number of blocks and send to server
int totalNumBlocks = (int)Math.ceil((file.length()*1.0) / blockSize);
System.out.println("File length is: " + file.length());
FTPCommand c = new FTPCommand("PUSH", Integer.toString(totalNumBlocks));
oos = new ObjectOutputStream(sock.getOutputStream());
oos.writeObject(c);
oos.flush();

// send to server block by block
FileInputStream fin = new FileInputStream(file);
while ((numBytesRead = fin.read(block)) != -1){
transferBlock = new FTPDataBlock(file.getName(), blockNumber, block);
blockNumber++;
System.out.println("Sending block " + transferBlock.getBlockNumber() + " of " + totalNumBlocks);
oos = new ObjectOutputStream(sock.getOutputStream());
oos.writeObject(transferBlock);
oos.flush();
}

fin.close();
System.out.println("PUSH Complete");

// get response from server
ois = new ObjectInputStream(sock.getInputStream());
FTPResponse response = (FTPResponse)ois.readObject();
statusArea.setText(response.getResponse());


} catch (IOException | ClassNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}

服务器代码:

else if (cmd.getCommand().equals("PUSH")){
// get total number of file blocks
int totalNumBlocks = Integer.parseInt(cmd.getParameters());

// get first block
in = new ObjectInputStream(sock.getInputStream());
FTPDataBlock currentBlock = (FTPDataBlock)in.readObject();

// create file and write first block to file
File file = new File (workingDirectory + File.separator + currentBlock.getFilename());
FileOutputStream fOut = new FileOutputStream(file);
fOut.write(currentBlock.getData());
fOut.flush();

// get remaining blocks
while(currentBlock.getBlockNumber()+1 <= totalNumBlocks){
in = new ObjectInputStream(sock.getInputStream());
currentBlock = (FTPDataBlock)in.readObject();
fOut.write(currentBlock.getData());
fOut.flush();
}

fOut.close();

// send response
FTPResponse response = new FTPResponse("File Received OK");
out = new ObjectOutputStream(sock.getOutputStream());
out.writeObject(response);
}

FTPDataBlock 类:

public class FTPDataBlock implements Serializable{

private static final long serialVersionUID = 1L;
private String filename;
private int blockNumber; // current block number
private byte[] data;
//constructors & accessors
}

我确信我在这里遗漏了一些小东西。有什么想法吗?

最佳答案

发生这种情况是因为服务器正在将整个 1024 字节 block 写入文件,即使实际写入该 block 的字节数少于 1024 字节。

解决方案(感谢 @kdgregory )是使用 FileInputStream.read() 的返回值来填充我的 FTPDataBlock 类中的新属性,int bytesWritten .

然后在服务器端我可以使用:

FileOutputStream.write(currentBlock.getData(), 0, currentBlock.getBytesWritten());

将确切的字节数写入文件,而不是每次都写入整个 block 。

关于Java - FTP 程序在传输过程中损坏文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21606473/

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