使用 java 套接字从服务器到客户端的文件传输。服务器端错误,传输到客户端的文件为空
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12637882/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
File Transfer from Server to Client using java sockets. Error on Server side and File transferred to client is empty
提问by highlander141
I have a Client and Server, where in client enters the filename, that filename will be checked on server side under pre-defined path, if the file exists, it will be transferred to client side under a similar pre-defined path. I have two problems :
我有一个客户端和服务器,其中客户端输入文件名,该文件名将在服务器端在预定义路径下检查,如果文件存在,它将在类似的预定义路径下传输到客户端。我有两个问题:
1) In Server, i am not able to compare the file under given pre-defined path, as it is showing FileNotFoundException (no such file/dir).
1) 在服务器中,我无法比较给定预定义路径下的文件,因为它显示 FileNotFoundException(没有这样的文件/目录)。
2) Even following the above exception, the file is transferred and it is empty.
2)即使出现上述异常,文件也被传输并且是空的。
Here are my Client and Server:
这是我的客户端和服务器:
Client:
客户:
import java.io.*;
import java.net.*;
import java.util.*;
public class ft2client
{
public static void main(String srgs[])throws IOException
{
Socket s=null;
BufferedReader get=null;
PrintWriter put=null;
try
{
s=new Socket("127.0.0.1",8085);
get=new BufferedReader(new InputStreamReader(s.getInputStream()));
put=new PrintWriter(s.getOutputStream(),true);
}
catch(Exception e)
{
System.exit(0);
}
String u,f;
System.out.println("Enter the file name to transfer from server:");
DataInputStream dis=new DataInputStream(System.in);
f=dis.readLine();
put.println(f);
File f1=new File(f);
String str = "/home/user/";
FileOutputStream fs=new FileOutputStream(new File(str,f1.toString()));
while((u=get.readLine())!=null)
{
byte jj[]=u.getBytes();
fs.write(jj);
}
fs.close();
System.out.println("File received");
s.close();
}
}
Server:
服务器:
import java.io.*;
import java.net.*;
import java.util.*;
public class ft2server
{
public static void main(String args[])throws IOException
{
ServerSocket ss=null;
try
{
ss=new ServerSocket(8085);
}
catch(IOException e)
{
System.out.println("couldn't listen");
System.exit(0);
}
Socket cs=null;
try
{
cs=ss.accept();
System.out.println("Connection established"+cs);
}
catch(Exception e)
{
System.out.println("Accept failed");
System.exit(1);
}
PrintWriter put=new PrintWriter(cs.getOutputStream(),true);
BufferedReader st=new BufferedReader(new InputStreamReader(cs.getInputStream()));
String s=st.readLine();
String str = "/home/user/Desktop/";
String path = str + s;
System.out.println("The requested file is path: "+path);
System.out.println("The requested file is : "+s);
File f=new File(path);
if(f.exists())
{
BufferedReader d=new BufferedReader(new FileReader(s));
String line;
while((line=d.readLine())!=null)
{
put.write(line);
put.flush();
}
d.close();
System.out.println("File transfered");
cs.close();
ss.close();
}
}
}
回答by Fluvid
See with binary data you have change the readers as they are capable of only characters and do not work with byte stream. moreover readline means read till end of line and in binary files ('\n') does not make too much sense.
This is from documentation of printWriter
使用二进制数据查看您已更改读取器,因为它们只能读取字符而不能使用字节流。此外, readline 意味着读取到行尾和二进制文件 ('\n') 没有太大意义。
这是来自printWriter的文档
It does not contain methods for writing raw bytes, for which a program should use unencoded byte streams.
It does not contain methods for writing raw bytes, for which a program should use unencoded byte streams.
What you would want now is to use byte arrays and write them as chunks like this :
你现在想要的是使用字节数组并将它们写成这样的块:
import java.io.*;
import java.net.*;
import java.util.*;
public class ft2server
{
public static void main(String args[])throws IOException
{
ServerSocket ss=null;
try
{
ss=new ServerSocket(8085);
}
catch(IOException e)
{
System.out.println("couldn't listen");
System.exit(0);
}
Socket cs=null;
try
{
cs=ss.accept();
System.out.println("Connection established"+cs);
}
catch(Exception e)
{
System.out.println("Accept failed");
System.exit(1);
}
BufferedOutputStream put=new BufferedOutputStream(cs.getOutputStream());
BufferedReader st=new BufferedReader(new InputStreamReader(cs.getInputStream()));
String s=st.readLine();
String str = "/home/milind/Desktop/";
String path = str + s;
System.out.println("The requested file is path: "+path);
System.out.println("The requested file is : "+s);
File f=new File(path);
if(f.isFile())
{
FileInputStream fis=new FileInputStream(f);
byte []buf=new byte[1024];
int read;
while((read=fis.read(buf,0,1024))!=-1)
{
put.write(buf,0,read);
put.flush();
}
//d.close();
System.out.println("File transfered");
cs.close();
ss.close();
}
}
}
The client
客户端
import java.io.*;
import java.net.*;
import java.util.*;
public class ft2client
{
public static void main(String srgs[])throws IOException
{
Socket s=null;
BufferedInputStream get=null;
PrintWriter put=null;
try
{
s=new Socket("127.0.0.1",8085);
get=new BufferedInputStream(s.getInputStream());
put=new PrintWriter(s.getOutputStream(),true);
String f;
int u;
System.out.println("Enter the file name to transfer from server:");
DataInputStream dis=new DataInputStream(System.in);
f=dis.readLine();
put.println(f);
File f1=new File(f);
String str = "/home/milind/";
FileOutputStream fs=new FileOutputStream(new File(str,f1.toString()));
byte jj[]=new byte[1024];
while((u=get.read(jj,0,1024))!=-1)
{
fs.write(jj,0,u);
}
fs.close();
System.out.println("File received");
s.close();
}catch(Exception e)
{
e.printStackTrace();
System.exit(0);
}
}
}
回答by av1987
Few things are for sure when you are dealing with the socket.
当您处理套接字时,很少有事情是确定的。
If at the other end you are reading line like get.readLine();
then from the sender program should have write into socket like this put.writeBytes("any string variable"+"\n")
or put.println("some string variable or literal.")
如果在另一端,您正在get.readLine();
从发送方程序中读取这样的行,则应该像这样写入套接字put.writeBytes("any string variable"+"\n")
或put.println("some string variable or literal.")
you are reading like get.readLine()
and you are writing the bytes whatever you are reading from the direct file.
您正在阅读,get.readLine()
并且您正在写入从直接文件中读取的任何字节。
This is my example how I do read,write on the socket when I need pure text to transfer in bytes.
这是我的示例,当我需要以字节为单位传输纯文本时,我如何在套接字上进行读取、写入操作。
Server {
...
soc = echoServer.accept();
out = new DataOutputStream(soc.getOutputStream());
out.flush();
in = new DataInputStream(soc.getInputStream());
out.writeBytes("some text in here \n");
out.flush();
...
}
Client{
...
soc = new Socket("10.210.13.121", 62436);
out = new DataOutputStream(soc.getOutputStream());
out.flush();
in = new DataInputStream(soc.getInputStream());
...
while(true)
if(in.available() > 0)
String str = in.readLine();
...
}
回答by Fluvid
Please use f.isFile() instead of f.exisits. It is a known issue.
In server you mistakenly wroteBufferedReader d=new BufferedReader(new FileReader(s));
instead of BufferedReader d=new BufferedReader(new FileReader(f));
Fixed codes
请使用 f.isFile() 而不是 f.exisits。这是一个已知问题。在服务器中你错误地写BufferedReader d=new BufferedReader(new FileReader(s));
而不是BufferedReader d=new BufferedReader(new FileReader(f));
固定代码
import java.io.*;
import java.net.*;
import java.util.*;
public class ft2server
{
public static void main(String args[])throws IOException
{
ServerSocket ss=null;
try
{
ss=new ServerSocket(8085);
}
catch(IOException e)
{
System.out.println("couldn't listen");
System.exit(0);
}
Socket cs=null;
try
{
cs=ss.accept();
System.out.println("Connection established"+cs);
}
catch(Exception e)
{
System.out.println("Accept failed");
System.exit(1);
}
PrintWriter put=new PrintWriter(cs.getOutputStream(),true);
BufferedReader st=new BufferedReader(new InputStreamReader(cs.getInputStream()));
String s=st.readLine();
String str = "/home/milind/Desktop/";
String path = str + s;
System.out.println("The requested file is path: "+path);
System.out.println("The requested file is : "+s);
File f=new File(path);
if(f.isFile())
{
BufferedReader d=new BufferedReader(new FileReader(f));
String line;
while((line=d.readLine())!=null)
{
put.write(line);
put.flush();
}
d.close();
System.out.println("File transfered");
cs.close();
ss.close();
}
}
}
Other one
另外一个
import java.io.*;
import java.net.*;
import java.util.*;
public class ft2client
{
public static void main(String srgs[])throws IOException
{
Socket s=null;
BufferedReader get=null;
PrintWriter put=null;
try
{
s=new Socket("127.0.0.1",8085);
get=new BufferedReader(new InputStreamReader(s.getInputStream()));
put=new PrintWriter(s.getOutputStream(),true);
String u,f;
System.out.println("Enter the file name to transfer from server:");
DataInputStream dis=new DataInputStream(System.in);
f=dis.readLine();
put.println(f);
File f1=new File(f);
String str = "/home/milind/";
FileOutputStream fs=new FileOutputStream(new File(str,f1.toString()));
while((u=get.readLine())!=null)
{
System.out.println(u);
byte jj[]=u.getBytes();
fs.write(jj);
}
fs.close();
System.out.println("File received");
s.close();
}catch(Exception e)
{
e.printStackTrace();
System.exit(0);
}
}
}
回答by user207421
Don't use Readers
and Writers
unless you know that the contents are characters. If you don't, use InputStreams
and OutputStreams
. In this case a ZIP file is certainly binary, not character data, so you are bound to corrupt it by using Readers
and Writers.
除非您知道内容是字符Readers
,Writers
否则不要使用and 。如果不这样做,请使用InputStreams
和OutputStreams
。在这种情况下,ZIP 文件肯定是二进制文件,而不是字符数据,因此您一定会通过使用Readers
和Writers.