Repository navigation
Expand file tree
/
Copy pathtest.java
More file actions
151 lines (134 loc) · 6.18 KB
/
Copy pathtest.java
File metadata and controls
151 lines (134 loc) · 6.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package com.example.sftp;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.time.Instant;
import java.util.Arrays;
import java.util.EnumSet;
import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.sftp.FileAttributes;
import net.schmizz.sshj.sftp.OpenMode;
import net.schmizz.sshj.sftp.RemoteFile;
import net.schmizz.sshj.sftp.SFTPClient;
import net.schmizz.sshj.sftp.SFTPException;
import net.schmizz.sshj.transport.verification.PromiscuousVerifier;
/**
* Simple sshj SFTP round-trip test.
*
* <p>Uploads a local file to a remote SFTP server and downloads it back,
* streaming through {@link RemoteFile} handles (no {@code put}/{@code get}).
*
* <p>Edit the constants below to point at your SFTP server, then run:
* {@code mvn compile exec:java}
*/
public class SftpTest {
// ---------------- edit these for your SFTP server ----------------
private static final String HOST = "4.230.148.191";
private static final int PORT = 22;
private static final String USERNAME = "michael";
// private key for key-based auth (OpenSSH/PKCS8/Putty formats supported)
private static final String PRIVATE_KEY = "private.txt";
// private static final String PASSWORD = "108129Y@oooo";
// Local file that will be created if missing, uploaded, then downloaded back
private static final Path LOCAL_SOURCE = Paths.get("test-data/hello.txt");
private static final Path LOCAL_DOWNLOAD = Paths.get("test-data/hello-downloaded.txt");
// Remote location on the SFTP server
private static final String REMOTE_DIR = "/tmp/sshj-test";
private static final String REMOTE_FILE = "hello-uploaded.txt";
public static void main(String[] args) throws IOException {
ensureLocalSourceFile();
try (SSHClient ssh = new SSHClient()) {
// Testing only: accept any host key. Use a known-hosts verifier in production!
ssh.addHostKeyVerifier(new PromiscuousVerifier());
ssh.connect(HOST, PORT);
// authenticate with the private key instead of username/password
ssh.authPublickey(USERNAME, PRIVATE_KEY);
// ssh.authPassword(USERNAME, PASSWORD);
System.out.printf("Connected to %s:%d as %s (key auth)%n", HOST, PORT, USERNAME);
try (SFTPClient sftp = ssh.newSFTPClient()) {
ensureRemoteDir(sftp);
// 1. Upload: open a remote file and stream local bytes into it
long uploaded = upload(sftp);
System.out.printf("UPLOAD : %d bytes -> %s/%s%n", uploaded, REMOTE_DIR, REMOTE_FILE);
// 2. Download: open the same remote file and stream it back down
long downloaded = download(sftp);
System.out.printf("DOWNLOAD : %d bytes -> %s%n", downloaded, LOCAL_DOWNLOAD);
// 3. Verify the round trip produced an identical file
boolean match = Arrays.equals(Files.readAllBytes(LOCAL_SOURCE),
Files.readAllBytes(LOCAL_DOWNLOAD));
System.out.println("MATCH : " + (match ? "OK - files are identical" : "MISMATCH - files differ!"));
System.out.println(match ? "SFTP TEST PASSED" : "SFTP TEST FAILED");
if (!match) {
System.exit(1);
}
}
} catch (Exception e) {
System.err.println("SFTP TEST FAILED: " + e.getMessage());
e.printStackTrace();
System.exit(1);
}
}
/**
* Upload: streams the local file into the open remote file handle via {@code rf.write(offset, ...)}.
* No {@code put} - every byte goes through the {@link RemoteFile}.
*/
private static long upload(SFTPClient sftp) throws IOException {
try (RemoteFile rf = sftp.open(REMOTE_DIR + "/" + REMOTE_FILE,
EnumSet.of(OpenMode.WRITE, OpenMode.CREAT, OpenMode.TRUNC),
FileAttributes.EMPTY)) {
byte[] buf = new byte[8192];
long offset = 0;
long total = 0;
try (InputStream in = Files.newInputStream(LOCAL_SOURCE)) {
int n;
while ((n = in.read(buf)) != -1) {
rf.write(offset, buf, 0, n); // write into the remote file handle
offset += n;
total += n;
}
}
return total;
}
}
/**
* Download: streams the open remote file handle into the local file via {@code rf.read(offset, ...)}.
* No {@code get} - every byte comes from the {@link RemoteFile}.
*/
private static long download(SFTPClient sftp) throws IOException {
try (RemoteFile rf = sftp.open(REMOTE_DIR + "/" + REMOTE_FILE)) { // default mode: READ
byte[] buf = new byte[8192];
long offset = 0;
long total = 0;
int n;
try (OutputStream out = Files.newOutputStream(LOCAL_DOWNLOAD,
StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) {
while ((n = rf.read(offset, buf, 0, buf.length)) != -1) { // read from the remote file handle
out.write(buf, 0, n);
offset += n;
total += n;
}
}
return total;
}
}
/** Creates the remote directory; ignores the "already exists" error. */
private static void ensureRemoteDir(SFTPClient sftp) throws IOException {
try {
sftp.mkdirs(REMOTE_DIR);
} catch (SFTPException e) {
// directory already exists - fine for a test
}
}
/** Creates a small local source file on first run so the test is self-contained. */
private static void ensureLocalSourceFile() throws IOException {
Files.createDirectories(LOCAL_SOURCE.getParent());
if (!Files.exists(LOCAL_SOURCE)) {
Files.writeString(LOCAL_SOURCE, "hello from sshj test - " + Instant.now() + "\n");
System.out.println("Created local test file: " + LOCAL_SOURCE.toAbsolutePath());
}
}
}