Отправка файла с настраиваемыми атрибутами по сети - PullRequest
2 голосов
/ 17 февраля 2011

Я хочу создать клиент-серверную программу, которая позволит клиенту отправлять файл на сервер вместе с некоторой информацией о файле (имя отправителя, описание и т. Д.).

Файл потенциально может быть довольно большим, так как это может быть текстовый, графический, аудио или видео файл, и поэтому я не хочу читать весь файл в байтовый массив перед отправкой,Я предпочел бы прочитать файл в блоках, отправив их по сети, а затем разрешив серверу добавить блоки в файл в его конце.

Однако я столкнулся с проблемой наилучшей отправки файлавместе с несколькими битами информации о самом файле.Я хотел бы как минимум отправить имя отправителя и описание, оба из которых будут введены пользователем в клиентскую программу, но это может измениться в будущем, поэтому должно быть гибким.

Что хорошоспособ сделать это, что также позволило бы мне «поток» отправляемого файла, а не читать его в целом и затем отправлять?

Ответы [ 3 ]

2 голосов
/ 17 февраля 2011

Сокеты изначально являются потоками байтов, поэтому у вас не должно быть проблем там.Я предлагаю вам иметь протокол, который выглядит следующим образом.

Это позволит вам отправлять произвольные свойства, если общая длина составляет менее 64 КБ.За ним следует файл, который может быть любой 63-битной длины и отправляется блоком за раз.(с буфером 8 КБ)

Сокет может использоваться для отправки большего количества файлов, если вы хотите.

DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
Properties fileProperties = new Properties();
File file = new File(filename);

// send the properties
StringWriter writer = new StringWriter();
fileProperties.store(writer, "");
writer.close();
dos.writeUTF(writer.toString());

// send the length of the file
dos.writeLong(file.length());

// send the file.
byte[] bytes = new byte[8*1024];
FileInputStream fis = new FileInputStream(file);
int len;
while((len = fis.read(bytes))>0) {
    dos.write(bytes, 0, len);
}
fis.close();
dos.flush();

для чтения

DataInputStream dis = new DataInputStream(socket.getInputStream());
String propertiesText = dis.readUTF();
Properties properties = new Properties();
properties.load(new StringReader(propertiesText));
long lengthRemaining = dis.readLong();
FileOutputStream fos = new FileOutputStream(outFilename);
int len;
while(lengthRemaining > 0 
   && (len = dis.read(bytes,0, (int) Math.min(bytes.length, lengthRemaining))) > 0) {
      fos.write(bytes, 0, len);
      lengthRemaining -= len;
}
fos.close();
0 голосов
/ 17 февраля 2011

Я рекомендую использовать протокол http для этого.Сервер может быть реализован с использованием сервлета, а Apache HttpClient может использоваться для клиента. В этой статье есть несколько хороших примеров.Вы можете отправить файл и параметры в одном запросе.И это тоже с очень небольшим кодом!

0 голосов
/ 17 февраля 2011

Вы можете создать программу на основе известного протокола, как FTP. И чтобы отправить метаинформацию, вы можете просто создать специальный файл с уникальным именем, который содержит информацию. Затем перенесите файл пользователя и метафайл с FTP.

В противном случае, снова используя FTP для файла, вы можете передать метаданные в потоке клиент-сервер вашей рукописной программы.

...