[英]Java TCP - Sending a file using DataOutputStream
嗨,謝謝你。
因此,當前,我正在嘗試讓我的TCP程序從目錄(這是服務器端)讀取文件,然后將該文件發送到請求該文件的套接字(客戶端)。
這是我的代碼:
服務器端:
File FileList = new File(".....filepath....");
Scanner scan = new Scanner(FileList);
//idToFile just searching for the name of the file the client asked for
String TheName = idToFile(Integer.toString(result));
//Opens the chosen file such as an image to be used
File myImageFile = new File("....filepath...." + TheName);
//sendResponse is a function with a writeUTF (but only works for strings)
sendResponse("#OK");
sendResponse(TheName);
sendResponse(Long.toString(myImageFile.length()));
//This line causes the error and says that it expected a string and not a file
output.writeUTF(myImageFile);
private void sendResponse(String response)
{
try
{
output.writeUTF(response);
}
catch (IOException ex)
{
ex.printStackTrace();
}
}
客戶端:
ClientHandler client = new ClientHandler();
//getResponse just catches the written strings, but it can't work with a file either
String TheMessage = client.getResponse();
String Name = client.getResponse();
long FileSize = Long.parseLong(client.getResponse());
這是ClientHandler的代碼:
public class ClientHandler
{
private static int port = 2016;
private DataInputStream input;
private DataOutputStream output;
private Socket cSocket;
public ClientHandler()
{
cSocket = null;
try
{
cSocket = new Socket("localhost", port); //connecting to the server
System.out.println("Client is connected on port " + port);
output = new DataOutputStream(cSocket.getOutputStream());
input = new DataInputStream(cSocket.getInputStream());
}
catch(IOException ex)
{
ex.printStackTrace();
}
}
public void sendMessage(String message) //checking if the message is sent
{
try
{
output.writeUTF(message);
output.flush();
System.out.println("Message sent to the server");
}
catch (IOException e)
{
e.printStackTrace();
}
}
public String getResponse()
{
String msg = "";
try
{
msg = input.readUTF();
}
catch(IOException ex)
{
ex.printStackTrace();
}
return msg;
}
}
那么,如何使用DataOutputStream將任何類型的文件從服務器發送到客戶端,以及我的客戶端如何使用DataInputStream捕獲該文件並將其保存到磁盤?
謝謝。
如下所示創建DataOutputStream和DataInputStream的新實例。
DataOutputStream socketOut = new DataOutputStream(socketObject.getOutputStream());
DataInputStream socketIn = new DataInputStream(socketObject.getInputStream());
為了快速參考,以下是示例類的摘錄
DataInputStream streamIn = new
DataInputStream(new
BufferedInputStream(client.getInputStream()));
String incomingDataLine = streamIn.readLine();
...
...
DataOutputStream socketOut = new DataOutputStream(client.getOutputStream());
socketOut.writeBytes(line + '\n');
=========編輯1:閱讀評論后
網絡上的任何內容都是1和0,即字節。 假設您要將映像從一台服務器傳輸到另一台服務器,那么推薦的方法是讓服務器讀取文件內容(以字節java.nio.Files.readAllBytes()
並將其寫入套接字)。
在客戶端,從套接字讀取所有字節(在實際項目中使用BufferedReader)並將其寫入磁盤。 您必須確保服務器和客戶端都使用相同的編碼。
使用BufferedInputStream和BufferedOutputStream代替DataXXXStream。
這將適用於任何文件類型-mp3,mp4,jpeg,png,acc,txt,java。 要使其在客戶端系統中可用,請確保創建具有正確擴展名的文件。
這里以一個簡單的服務器為例,該服務器將二進制文件發送到每個客戶端,而無需進一步的交互。
套接字提供輸出流以將字節寫入客戶端。 我們有一個要發送的文件“ picin.jpg”,因此我們需要將此文件的每個字節寫入套接字的輸出流。 為了做到這一點,我們使用包裹在BufferedInputStream
的FileInputStream
。
package networking;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) {
try {
ServerSocket ss = new ServerSocket();
ss.bind(new InetSocketAddress("localhost", 4711));
for(;;) {
Socket sock = ss.accept();
System.out.println("Connected to " + sock.getInetAddress());
try (
InputStream in = new BufferedInputStream(new FileInputStream("picin.jpg"));
OutputStream out = sock.getOutputStream();
)
{
int bytesSent = Util.copy(in, out);
System.out.println(String.format("%d bytes sent.", bytesSent));
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
我將copy方法提取到util類中,因為我們需要客戶端中完全相同的方法。 我們使用一個小字節數組作為緩沖區,然后將一個塊又一個塊從一個流復制到另一個流。
package networking;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class Util {
public static int copy(InputStream in, OutputStream out) throws IOException {
byte[] buf = new byte[2048];
int bytesRead = 0;
int totalBytes = 0;
while((bytesRead = in.read(buf)) != -1) {
totalBytes += bytesRead;
out.write(buf, 0, bytesRead);
}
return totalBytes;
}
}
客戶端打開與服務器的連接,並將接收到的字節寫入文件。 套接字為輸入流提供來自服務器的字節。 我們使用包裹在BufferedOutputStream
的FileOutputStream
寫入文件。 我們使用相同的Util.copy()
方法將字節實際上從一個流復制到另一個流。
package networking;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
public class Client {
public static void main(String[] args) {
try {
Socket sock = new Socket(InetAddress.getByName("localhost"), 4711);
try(
InputStream in = sock.getInputStream();
OutputStream out = new BufferedOutputStream(new FileOutputStream("picout.jpg"))
)
{
System.out.println("Connected to " + sock.getRemoteSocketAddress());
int bytesCopied = Util.copy(in, out);
System.out.println(String.format("%d bytes received", bytesCopied));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
注意:流通過try-with-ressources語句自動關閉。 關閉套接字,同時關閉相應的流。
Java 8包含一些方便的方法,可將字節從文件復制到輸出流或從輸入流復制到文件。 參見java.nio.file.Files
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.