Хорошо, таким образом, я работаю над проектом, где я использую программу Java для инициирования сокетного соединения между двумя классами (a FileSender
и FileReceiver
). Моя основная идея состояла в том что FileSender
был бы похож на это:
try {
writer = new DataOutputStream(connect.getOutputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//While we have bytes to send
while(filein.available() >0){
//We write them out to our buffer
writer.write(filein.read(outBuffer));
writer.flush();
}
//Then close our filein
filein.close();
//And then our socket;
connect.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Конструктор содержит код, который проверяет, чтобы видеть, существует ли файл, и что сокет подключен и так далее. В моем FileReader это хотя:
input = recvSocket.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(input.getInputStream()));
FileOutputStream fOut= new FileOutputStream(filename);
String line = br.readLine();
while(line != null){
fOut.write(line.getBytes());
fOut.flush();
line = br.readLine();
}
System.out.println("Before RECV close statements");
fOut.close();
input.close();
recvSocket.close();
System.out.println("After RECV clsoe statements");
Вся внутренняя часть блок try-catch. Так, что я пытаюсь сделать, имеют FileSender
чтение в файле, преобразование в байты, отправка и промытие его. FileReceiver
, затем чтения в байтах, пишет в fileOut, сбросы, и продолжает ожидать больше. Я удостоверяюсь, что закрыл все вещи, которые я открываю, так... здесь прибывает странная часть.
То, когда я пытаюсь открыть созданный текстовый файл в Eclipse, он говорит мне "Ошибку SWT, произошло... рекомендуемое выйти, инструментальные средства... дополнительную информацию см. в .log".. Другое окно открывается, говоря "Необработанное исключение цикла событий, (больше никаких дескрипторов)". Однако, если я пытаюсь открыть отправленный текстовый файл в notepad2, я добираюсь
ThisIsASentTextfile
Который хорош (хорошо, минус то, что должны быть разрывы строки, но я работаю над этим...). Кто-либо знает, почему это происходит? И в то время как мы проверяем, как добавить разрывы строки?
(И действительно ли это - особенно плохой способ передать файлы по Java, не получая некоторые другие библиотеки?)
Править: Обновление: Я изменил свой код на следующий (FileReceiver), не изменяя отправителя:
try {
input = recvSocket.accept();
//InputStream br = new InputStream(input.getInputStream());
FileWriter fOut= new FileWriter(filename);
//BufferedWriter out = new BufferedWriter(fOut);
//String line = br.
byte info = (byte) input.getInputStream().read();
while((int)info != 0){
fOut.write(info);
fOut.flush();
info = (byte) input.getInputStream().read();
}
fOut.flush();
System.out.println("Before RECV close statements");
fOut.close();
//input.close();
recvSocket.close();
System.out.println("After RECV clsoe statements");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Это работает. Я получаю текстовый файл, который является правильным размером в байтах (прежде чем я получал размер стандарта 4 КБ), и имеет правильное форматирование. Я собираюсь попробовать его на изображении затем и держать Вас в курсе.
С первого взгляда: Почему вы используете DataOutputStream ? Совершенно неадекватно для вашей цели. Просто используйте предоставленный вами выходной поток:
writer = connect.getOutputStream();
BTW, это сомнительная практика называть "writer" этой переменной, Java делает четкое концептуальное различие между читателями/писателями (ориентированными на char) и потоками (ориентированными на байты).
UPDATE: Еще одна плохая практика, которая влечет за собой неприятности: вы смешиваете читатели/писатели (ориентированные на символы) и потоки (ориентированные на байты) без необходимости - и без указания кодировки charset.
BufferedReader br = new BufferedReader(new InputStreamReader(input.getInputStream()));
Вы должны использовать Reader, когда вы имеете дело с текстом (в известной кодировке), используйте InputStream, если вы имеете дело только с байтами.
Что касается разрывов строк, BufferedReader.readLine () считывает данные, завершенные переводом строки, но не возвращает перевод строки. Итак, когда вы напишете его обратно, вы захотите написать перевод строки. В качестве альтернативы вы можете читать и записывать байты, поэтому вы не закончите ошибочное преобразование символов перевода строки или повреждение двоичных файлов, которые включают значения ascii для перевода строки или возврата каретки.