Отправка файлов с клиента на сервер с использованием сокетов, но получение некоторых файлов нулевого размера

я пишу код, где

  1. клиент берет имена файлов (текстовые файлы) из командной строки
  2. клиент преобразует каждый файл в массив байтов, а затем отправляет этот массив на сервер.
  3. сервер запускает новый поток, каждый поток преобразует массив байтов в новый файл в каком-то указанном каталоге.

Мой клиентский код

для клиентской стороны

import java.io.*;
import java.net.*;

class Client
{
    public static void main(String args[])
    {
        try
        {
            int len=args.length;
            if(len== 0)
            {
                System.out.println("Invalid Number of Arguements");
                throw new Exception();
            }
            else
            {
                int i=0;
                while(i<len)
                {          
                    Socket s=new Socket("localhost",2222);
                    File f=new File(args[i++]);
                    if(f.exists())
                    {
                        OutputStream os=s.getOutputStream();
                        FileInputStream fr=new FileInputStream(f);
                        s.setSendBufferSize(fr.available());
                        byte data[]=new byte[fr.available()];
                        fr.read(data);
                        os.write(data);
                        os.flush();
                        os.close();
                        System.out.println("Sending file : "+f.getName()+" with size "+data.length);
                        fr.close();
                    }
                    else
                    {
                        System.out.println("File : "+args[i++]+" doesn't exist.");
                    }

                    s.close();
                }
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
}

для серверной части

import java.net.*;
import java.io.*;
import java.util.Date;

public class Server
{
    public static final String dir_to_store_files="c:\\myfiles\\";

    public static void main(String[] args) throws Exception
    {
        ServerSocket ss=new ServerSocket(2222);
        ss.setReceiveBufferSize(51200);
        ss.setReuseAddress(true);

        Socket s=null;
        while( (s=ss.accept()) != null)
        {
            new Thread(new ServerThreads(s,dir_to_store_files)).start();
            s=null;
        }
        ss.close();
    }
}

class ServerThreads implements Runnable
{
    private static int fileNounce=0;
    Socket s;
    String directory;

    ServerThreads(Socket s,String directory)
    {
        this.s=s;
        this.directory=directory;
    }

    public void run()
    {
        try
        {
            InputStream is=s.getInputStream();
            File f=new File(directory+"\\NewFile-"+fileNounce+".txt");
            while(f.exists())
            {
                    fileNounce++;
                    f=new File(directory+"\\NewFile "+fileNounce+".txt");
            }

            fileNounce++;
            f.createNewFile();

            FileOutputStream fos=new FileOutputStream(f);
            byte data[]=new byte[is.available()];
            System.out.print(is.available()+ " bytes are received from "+s.getRemoteSocketAddress());
            is.read(data);
            System.out.println("\t\tCreating file : "+f.getAbsolutePath()+" at : "+new Date()+" of size : "+data.length);
            is.close();
            fos.write(data);
            fos.flush();
            fos.close();
            s.close();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
}

Проблема: сервер не может правильно получить файлы, что означает, что иногда новые файлы создаются с нулевым размером (без данных). Например, я проверил отправку 239 c-файлов с помощью клиента java диапазон 180-235) Даже некоторые файлы, которые он получает, имеют нулевой размер.


person Dinesh Chander    schedule 27.04.2013    source источник


Ответы (1)


fr. available() - это не то, что вы думаете... Вам нужен File.length() и цикл для чтения байтов файла для отправки на сервер...

is.available() также неверен... рассмотрим клиентскую сторону, которая выглядит так:

byte[] buffer = new byte[4096];
int len = 0;
while ((len = fr.read(buffer)) >= 0) {
   os.write(buffer, 0, len);
}
person rolfl    schedule 27.04.2013
comment
нет, available() указывает на то, сколько байтов можно прочитать без блокировки... и даже тогда это подсказка. Например, InputStream() из сокета будет иметь available() == 0, пока клиент не отправит данные.... - person rolfl; 28.04.2013
comment
На самом деле я хочу копировать файлы (обычно текстовые файлы) из одной системы в другую (где будет происходить дальнейшая обработка). Так должен ли я использовать сокеты или обычное копирование файлов (с точки зрения производительности) ?? - person Dinesh Chander; 29.04.2013
comment
Если расположение от и до находится на локальном компьютере, используйте Files.copy(...) (из java.nio.file.Files ), в противном случае используйте сокеты - person rolfl; 29.04.2013