- Реализация FTP-клиента на Java
- 1. Обзор
- 2. Настройка
- 3. Поддержка FTP в JDK
- 4. Подключение
- 5. Список файлов
- 6. Загрузка
- 7. Загрузка
- 8. Заключение
- Читайте ещё по теме:
- File Transfer Protocol [FTP] Implementation in Java
- Saved searches
- Use saved searches to filter your results more quickly
- License
- 04xRaynal/File-Transfer_Java-Socket
- Name already in use
- Sign In Required
- Launching GitHub Desktop
- Launching GitHub Desktop
- Launching Xcode
- Launching Visual Studio Code
- Latest commit
- Git stats
- Files
- README.md
- About
Реализация FTP-клиента на Java
Узнайте, как легко взаимодействовать с внешним FTP-сервером на Java.
1. Обзор
В этом уроке мы рассмотрим, как использовать Apache Commons Net библиотека для взаимодействия с внешним FTP-сервером.
2. Настройка
При использовании библиотек, которые используются для взаимодействия с внешними системами, часто рекомендуется написать несколько дополнительных интеграционных тестов, чтобы убедиться, что мы правильно используем библиотеку.
В настоящее время мы обычно используем Docker для запуска этих систем для наших интеграционных тестов. Однако, особенно при использовании в пассивном режиме, FTP-сервер не является самым простым приложением для прозрачного запуска внутри контейнера, если мы хотим использовать динамические сопоставления портов (что часто необходимо для выполнения тестов на общем сервере CI).
Вот почему мы будем использовать MockFtpServer вместо этого, поддельный/тупиковый FTP-сервер, написанный на Java, который предоставляет обширный API для удобного использования в тестах JUnit:
commons-net commons-net 3.6 org.mockftpserver MockFtpServer 2.7.1 test
Рекомендуется всегда использовать последнюю версию. Их можно найти здесь и там .
3. Поддержка FTP в JDK
Удивительно, но в некоторых вариантах JDK уже есть базовая поддержка FTP в виде Удивительно, но в некоторых вариантах JDK уже есть базовая поддержка FTP в виде .
Однако мы не должны использовать этот класс напрямую, и вместо этого можно использовать JDK java.net. Класс URL как абстракция.
Эта поддержка FTP очень проста, но использует удобные API-интерфейсы java.nio.file.Файлы, этого может быть достаточно для простых случаев использования:
@Test public void givenRemoteFile_whenDownloading_thenItIsOnTheLocalFilesystem() throws IOException < String ftpUrl = String.format( "ftp://user:[email protected]:%d/foobar.txt", fakeFtpServer.getServerControlPort()); URLConnection urlConnection = new URL(ftpUrl).openConnection(); InputStream inputStream = urlConnection.getInputStream(); Files.copy(inputStream, new File("downloaded_buz.txt").toPath()); inputStream.close(); assertThat(new File("downloaded_buz.txt")).exists(); new File("downloaded_buz.txt").delete(); // cleanup >
Поскольку в этой базовой поддержке FTP уже отсутствуют основные функции, такие как списки файлов, мы будем использовать поддержку FTP в библиотеке Apache Net Commons в следующих примерах.
4. Подключение
Сначала нам нужно подключиться к FTP-серверу. Давайте начнем с создания класса FTPClient.
Он будет служить в качестве API абстракции для реального FTP-клиента Apache Commons Net:
class FtpClient < private String server; private int port; private String user; private String password; private FTPClient ftp; // constructor void open() throws IOException < ftp = new FTPClient(); ftp.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out))); ftp.connect(server, port); int reply = ftp.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) < ftp.disconnect(); throw new IOException("Exception in connecting to FTP Server"); >ftp.login(user, password); > void close() throws IOException < ftp.disconnect(); >>
Нам нужен адрес сервера и порт, а также имя пользователя и пароль. После подключения необходимо проверить код ответа, чтобы убедиться, что соединение прошло успешно. Мы также добавляем PrintCommandListener , чтобы распечатать ответы, которые мы обычно видим при подключении к FTP-серверу с помощью инструментов командной строки в stdout.
Поскольку наши интеграционные тесты будут иметь некоторый шаблонный код, такой как запуск/остановка MockFtpServer и подключение/отключение нашего клиента, мы можем сделать это в методах @Before и @After :
public class FtpClientIntegrationTest < private FakeFtpServer fakeFtpServer; private FtpClient ftpClient; @Before public void setup() throws IOException < fakeFtpServer = new FakeFtpServer(); fakeFtpServer.addUserAccount(new UserAccount("user", "password", "/data")); FileSystem fileSystem = new UnixFakeFileSystem(); fileSystem.add(new DirectoryEntry("/data")); fileSystem.add(new FileEntry("/data/foobar.txt", "abcdef 1234567890")); fakeFtpServer.setFileSystem(fileSystem); fakeFtpServer.setServerControlPort(0); fakeFtpServer.start(); ftpClient = new FtpClient("localhost", fakeFtpServer.getServerControlPort(), "user", "password"); ftpClient.open(); >@After public void teardown() throws IOException < ftpClient.close(); fakeFtpServer.stop(); >>
Установив порт управления фиктивным сервером в значение 0, мы запускаем фиктивный сервер и свободный случайный порт.
Вот почему мы должны получить фактический порт при создании Ftp-клиента после запуска сервера, используя fakeFtpServer.getServerControlPort() .
5. Список файлов
Первым фактическим вариантом использования будет список файлов.
Давайте сначала начнем с теста в стиле TDD:
@Test public void givenRemoteFile_whenListingRemoteFiles_thenItIsContainedInList() throws IOException < Collectionfiles = ftpClient.listFiles(""); assertThat(files).contains("foobar.txt"); >
Сама реализация столь же проста. Чтобы сделать возвращаемую структуру данных немного проще для этого примера, мы преобразуем возвращаемый FTPFile массив преобразуется в список Строк с помощью Java 8 Потоков:
Collection listFiles(String path) throws IOException
6. Загрузка
Для загрузки файла с FTP-сервера мы определяем API.
Здесь мы определяем исходный файл и место назначения в локальной файловой системе:
@Test public void givenRemoteFile_whenDownloading_thenItIsOnTheLocalFilesystem() throws IOException < ftpClient.downloadFile("/buz.txt", "downloaded_buz.txt"); assertThat(new File("downloaded_buz.txt")).exists(); new File("downloaded_buz.txt").delete(); // cleanup >
FTP-клиент Apache Net Commons содержит удобный API, который будет напрямую записывать данные в определенный выходной поток. Это означает, что мы можем использовать это напрямую:
void downloadFile(String source, String destination) throws IOException
7. Загрузка
MockFtpServer предоставляет некоторые полезные методы для доступа к содержимому своей файловой системы. Мы можем использовать эту функцию для написания простого интеграционного теста для функции загрузки:
@Test public void givenLocalFile_whenUploadingIt_thenItExistsOnRemoteLocation() throws URISyntaxException, IOException < File file = new File(getClass().getClassLoader().getResource("baz.txt").toURI()); ftpClient.putFileToPath(file, "/buz.txt"); assertThat(fakeFtpServer.getFileSystem().exists("/buz.txt")).isTrue(); >
Загрузка файла работает с точки зрения API очень похоже на его загрузку, но вместо использования OutputStream нам нужно предоставить InputStream вместо этого:
void putFileToPath(File file, String path) throws IOException
8. Заключение
Мы видели, что использование Java вместе с Apache Net Commons позволяет нам легко взаимодействовать с внешним FTP-сервером как для чтения, так и для записи.
Как обычно, полный код этой статьи доступен в нашем репозитории GitHub .
Читайте ещё по теме:
File Transfer Protocol [FTP] Implementation in Java
Develop a client server application which implements File Transfer protocol. Let the
client side request for files and the server reads it and sends to the client.
Input and Output Requirements:
The client accepts filename through the keyboard and sends it to the server. The server reads the file and transfers the content back to the client.
Algorithm: server side
Begin
Create an object of server socket class and listen for incoming client connection in a specified port.
When a client connection is established, create input and output streams for this connection.
While (true)
a. Read a file name from the input stream.
b. Read the content of the file requested by the client.
c. Send the file content to the client.
d. Close server and client socket.
End
Algorithm: client side
Begin
Establish a connection to the server program. Use IP address and port number of the server.
Crete input and output streams for the established connection.
Read filename from the keyboard and send to the server.
Display contents of file sent to the server.
Close the connection.
End
//FTP Server….. import java.io.*; import java.net.*; public class FTP_Server { ServerSocket server; // create a server. Socket con= null; // to establish a connection ObjectOutputStream out; ObjectInputStream in; String filename = ""; String contents = ""; File file=null; void start() throws UnknownHostException,IOException ,FileNotFoundException { try { server = new ServerSocket(2004,10); // port,max Queue. System.out.println("Server - listening on port " + 2004); System.out.println("Server - Waiting for the Client. "); con = server.accept(); System.out.println("Server - Connection received from " + con.getInetAddress().getHostName()); out = new ObjectOutputStream(con.getOutputStream()); in = new ObjectInputStream(con.getInputStream()); serverMessage("Server - Connection to Client Failed. "); do { try { filename = (String) in.readObject(); System.out.println("Server > Got filename From Client -> " + filename); File file = new File(filename); FileInputStream fin = new FileInputStream(file); DataInputStream din = new DataInputStream(fin); while((contents = din.readLine()) != null) { System.out.println("Inside" + contents); serverMessage(contents); //sending file contents. } if(filename.equals("bye")) serverMessage("bye"); } catch(ClassNotFoundException e){ System.out.println(e.getMessage()); } }while(!filename.equals("bye")); } catch(IOException e){} finally { try { in.close(); out.close(); server.close(); } catch(IOException e) { System.out.println(e.getMessage()); } } } void serverMessage(String str) throws IOException { try { out.writeObject(str); // WRITING TO SERVER'S OUTPUT BUFFER. out.flush(); // clearing the output buffer. System.out.println("Server -writing Message to Server's output buffer. " + str); } catch(IOException ioe){ } } public static void main(String[] args) throws UnknownHostException ,IOException ,NullPointerException { FTP_Server server = new FTP_Server(); while(true) { try { server.start(); } catch(NullPointerException e){} } } }
//FTP Client ….. import java.io.*; import java.net.*; public class FTP_Client { Socket client = null; // create a client. String file = "test.txt"; ObjectOutputStream out; ObjectInputStream in; String msg; void start() throws UnknownHostException,IOException { System.out.println("Filename : "+ file); try { client = new Socket("localhost",2004); //inetaddress ip ,port System.out.println("Client > Connecting to server. "); out = new ObjectOutputStream(client.getOutputStream()); in=new ObjectInputStream(client.getInputStream()); ClientMessage("Client > Connection to server Failed. "); do { try { msg = (String)in.readObject(); System.out.println("Client > Message From Server ->" + msg); ClientMessage(file); } catch(ClassNotFoundException e){ System.out.println(e.getMessage()); } }while(!msg.equals("bye")); } catch(IOException e){} } void ClientMessage(String str) throws IOException { try { System.out.println("Client > Writing to Client's output buffer. " + str ); out.writeObject(str); // WRITING TO CLIENT'S OUTPUT BUFFER. out.flush(); // clearing the output buffer. } catch(IOException ioe){} } public static void main(String[] args) throws UnknownHostException ,IOException { FTP_Client client = new FTP_Client(); client.start(); } }
//FTP Client ….. import java.io.*; import java.net.*; public class FTP_Client < Socket client = null; // create a client. String file = "test.txt"; ObjectOutputStream out; ObjectInputStream in; String msg; void start() throws UnknownHostException,IOException < System.out.println("Filename : "+ file); try < client = new Socket("localhost",2004); //inetaddress ip ,port System.out.println("Client >Connecting to server. «); out = new ObjectOutputStream(client.getOutputStream()); in=new ObjectInputStream(client.getInputStream()); ClientMessage(«Client > Connection to server Failed. «); do < try < msg = (String)in.readObject(); System.out.println("Client >Message From Server ->» + msg); ClientMessage(file); > catch(ClassNotFoundException e) < System.out.println(e.getMessage()); >>while(!msg.equals(«bye»)); > catch(IOException e)<> > void ClientMessage(String str) throws IOException < try < System.out.println("Client >Writing to Client’s output buffer. » + str ); out.writeObject(str); // WRITING TO CLIENT’S OUTPUT BUFFER. out.flush(); // clearing the output buffer. > catch(IOException ioe)<> > public static void main(String[] args) throws UnknownHostException ,IOException < FTP_Client client = new FTP_Client(); client.start(); >>
Server side
Server – listening on port 2004
Server – Waiting for the Client…..
Server > Got filename from Client -> test.txt
Filename : test.txt
Client > Connecting to server…..
Client > message from server -> Hello I am sandeep.
Saved searches
Use saved searches to filter your results more quickly
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.
File Transfer Program via Java Socket Programming to transfer files between machines.
License
04xRaynal/File-Transfer_Java-Socket
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Sign In Required
Please sign in to use Codespaces.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching Xcode
If nothing happens, download Xcode and try again.
Launching Visual Studio Code
Your codespace will open once ready.
There was a problem preparing your codespace, please try again.
Latest commit
Git stats
Files
Failed to load latest commit information.
README.md
File Transfer Program via Java Socket Programming
Server and Client class connect with each other using TCP [connection-oriented protocol] Socket (Socket and ServerSocket classes).
Server sends File Options to the Client and the Client responds to them.
Here the File Naming Convention used is:
DepartmentID-AccountID eg: 1234-123456
About
File Transfer Program via Java Socket Programming to transfer files between machines.