#java #file-transfer #client-server
#java #передача файлов #клиент-сервер
Вопрос:
Я пытаюсь выполнить простую передачу файлов с сервера на клиент.
Это должно выглядеть следующим образом:
Клиент запрашивает файл.
Сервер отправляет файл клиенту.
Теперь в коде (внизу) (это единственный код, который я нашел, и его было трудно найти) Она отправляет мне только текстовый файл «good» (и даже это приводит только к одной строке в клиенте). Если я попытаюсь отправить файл любого другого типа (например, изображение или rar-файл), он будет поврежден.
Итак, не мог бы кто-нибудь, пожалуйста, помочь мне найти какой-нибудь рабочий код (на Java), который может отправлять и получать файлы всех типов, или объяснить мне, в чем проблема с этим кодом.
На стороне сервера:
public class FileServer {
public static void main(String args[])throws IOException
{
ServerSocket ss=null;
try
{
ss=new ServerSocket(8081);
}
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();
System.out.println("The requested file is : " s);
File f=new File(s);
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();
}
}
}
На стороне клиента:
class MyClient {
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",8081);
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("c:\output");
FileOutputStream fs=new FileOutputStream(f1);
while((u=get.readLine())!=null)
{
byte jj[]=u.getBytes();
fs.write(jj);
}
fs.close();
System.out.println("File received");
s.close();
}
}
да, ссссссссссссссссссссссссссссссссссссссссссссссссссссссссссссс
наконец-то…
Это изменения
на стороне клиента.
class MyClient {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",8081);
get=new BufferedReader(new InputStreamReader(s.getInputStream()));
put=new PrintWriter(s.getOutputStream(),true);
}
catch(Exception e)
{
System.exit(0);
}
InputStreamReader get2=new InputStreamReader(s.getInputStream());
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("c:\output");
FileOutputStream fs=new FileOutputStream(f1);
BufferedInputStream d=new BufferedInputStream(s.getInputStream());
BufferedOutputStream outStream = new BufferedOutputStream(new FileOutputStream(f1));
byte buffer[] = new byte[1024];
int read;
while((read = d.read(buffer))!=-1)
{
outStream.write(buffer, 0, read);
outStream.flush();
}
//while((u=get.readLine())!=null)
// {
// byte jj[]=u.getBytes();
// fs.write(jj);
//}
fs.close();
System.out.println("File received");
s.close();
}
}
На стороне сервера.
public class FileServer {
public static void main(String args[])throws IOException
{
ServerSocket ss=null;
try
{
ss=new ServerSocket(8081);
}
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();
System.out.println("The requested file is : " s);
File f=new File(s);
if(f.exists())
{
BufferedInputStream d=new BufferedInputStream(new FileInputStream(s));
BufferedOutputStream outStream = new BufferedOutputStream(cs.getOutputStream());
byte buffer[] = new byte[1024];
int read;
while((read = d.read(buffer))!=-1)
{
outStream.write(buffer, 0, read);
outStream.flush();
}
d.close();
System.out.println("File transfered");
cs.close();
ss.close();
}
}
}
Большое спасибо всем вам…
Комментарии:
1. «кто-нибудь, пожалуйста, помогите мне найти какой-нибудь рабочий код (на Java), который cna отправляет и получает файлы всех типов, пожалуйста». Пожалуйста, правильно произносите такие слова, как «пожалуйста», используйте средство проверки орфографии и найдите свою клавишу shift. Для большей ясности в коде выберите один из двух распространенных способов заключать блоки кода в квадратные скобки и делать отступы, а затем придерживайтесь его. Для получения более точных ответов задайте вопрос.
2. не забудьте отметить вопрос как решенный 😉
Ответ №1:
Вы не должны использовать Reader в этом случае. Предполагается, что Reader обрабатывает, когда вы читаете / записываете символьные данные (текст), а не двоичные. Используйте какой-то InputStream
http://download.oracle.com/javase/tutorial/i18n/text/stream.html
Обновление: в вашей серверной части после f.exist():
BufferedInputStream d=new BufferedInputStream(new FileInputStream(s));
BufferedOutputStream outStream = new BufferedOutputStream(cs.getOutputStream());
byte buffer[] = new byte[1024];
int read;
while((read = d.read(buffer))!=-1)
{
outStream.write(buffer, 0, read);
outStream.flush();
}
d.close();
System.out.println("File transfered");
cs.close();
ss.close();
Комментарии:
1. но я использую InputStreamReader. «get=new BufferedReader(новый InputStreamReader(s.getInputStream()));»
2. @dan, InputStreamReader — это программа для чтения. Она считывает байты, а затем преобразует их в символы. Итак, вы читаете символы, а не байты. Попробуйте заменить все readLine () на read() InputStream. На сервере вам нужно будет прочитать массив байтов из файла, записать этот массив в сокет. На клиенте считывается массив байтов из сокета и записывается в файл.
3. когда вы говорите «записать этот массив в socke», что вы имеете в виду?? как я отправляю это клиенту?
4. @dan, смотрите обновления моего ответа. Я не тестировал, но думаю, что это должно сработать. То же самое для клиента.
Ответ №2:
Класс Reader / Writer предназначен только для символьного потока, Reader doc. Вы должны использовать BufferedInputStream / BufferedOutputStream или что-то подобное для необработанных / двоичных данных.
Ответ №3:
Да, но InpustStreamReader по-прежнему является средством чтения, которое попытается преобразовать базовые байты в символьные данные, а не в двоичные данные. Поскольку вы просто пытаетесь отправить необработанные байты файла, не используйте ничего с «reader» или «writer» в имени — вместо этого используйте InputStream и OutputStream (и их подклассы) как на сервере, так и на клиенте.
Комментарии:
1. извините, но я немного путаю. вы говорите, что мне нужно отправить двоичные данные, верно? теперь для этого мне нужно преобразовать мой файл в массив байтов, но как я на самом деле отправляю его через «put.write (строка)» в моем коде, потому что мой «BufferedReader» (который создается из InputStreamReader) прочитал только то, что возвращает int или string …
2. Вам не нужно преобразовывать файл в массив байтов, вам просто нужно не использовать какой-либо класс ввода-вывода со словом «Reader» или «Writer» в названии. Поэтому вообще не используйте PrintWriter или BufferedReader в вашем серверном или клиентском классе. Замените их использование соответствующими классами, которые реализуют InputStream и OutputStream из библиотеки ввода-вывода Java