diff --git a/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/Job.java b/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/Job.java index d6dab95f480dc18aba452bd2b00b5d8d02be97cb..8dc3b3446259f7c170c67535ab8ab81f7e7ceabb 100644 --- a/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/Job.java +++ b/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/Job.java @@ -19,6 +19,8 @@ import org.scijava.plugin.Parameter; import cz.it4i.fiji.haas_java_client.HaaSClient; import cz.it4i.fiji.haas_java_client.JobInfo; import cz.it4i.fiji.haas_java_client.JobState; +import cz.it4i.fiji.haas_java_client.ProgressNotifier; +import net.imagej.updater.util.Progress; public class Job { @@ -46,10 +48,37 @@ public class Job { private JobInfo jobInfo; - public Job(Path path, Collection<Path> files, Supplier<HaaSClient> haasClientSupplier) throws IOException { + final private Progress dummy = new Progress() { + + @Override + public void setTitle(String title) { + } + + @Override + public void setItemCount(int count, int total) { + } + + @Override + public void setCount(int count, int total) { + } + + @Override + public void itemDone(Object item) { + } + + @Override + public void done() { + } + + @Override + public void addItem(Object item) { + } + }; + + public Job(Path path, Collection<Path> files, Supplier<HaaSClient> haasClientSupplier, Progress progress) throws IOException { this(haasClientSupplier); HaaSClient client = this.haasClientSupplier.get(); - long id = client.start(files, "TestOutRedirect", Collections.emptyList()); + long id = client.start(files, "TestOutRedirect", Collections.emptyList(), new P_ProgressNotifierAdapter(progress)); jobDir = path.resolve("" + id); Files.createDirectory(jobDir); state = updateJobInfo().getState(); @@ -91,11 +120,15 @@ public class Job { return jobInfo = haasClientSupplier.get().obtainJobInfo(getJobId()); } - synchronized public void download() { + public void download() { + download(dummy); + } + + synchronized public void download(Progress progress) { if (!needsDownload()) { throw new IllegalStateException("Job: " + getJobId() + " dosn't need download"); } - haasClientSupplier.get().download(getJobId(), jobDir); + haasClientSupplier.get().download(getJobId(), jobDir, new P_ProgressNotifierAdapter(progress)); needsDownload = false; try { saveJobinfo(); @@ -150,4 +183,39 @@ public class Job { public Calendar getEndTime() { return jobInfo.getEndTime(); } + + private class P_ProgressNotifierAdapter implements ProgressNotifier { + private Progress progress; + + public P_ProgressNotifierAdapter(Progress progress) { + super(); + this.progress = progress; + } + + public void setTitle(String title) { + progress.setTitle(title); + } + + public void setCount(int count, int total) { + progress.setCount(count, total); + } + + public void addItem(Object item) { + progress.addItem(item); + } + + public void setItemCount(int count, int total) { + progress.setItemCount(count, total); + } + + public void itemDone(Object item) { + progress.itemDone(item); + } + + public void done() { + progress.done(); + } + + + } } diff --git a/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/JobManager.java b/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/JobManager.java index 2a6cd6c5a472fdc64bf06daf70c13539a65d69e6..e18b72e7682fa14368a66a619d330891f9e98e39 100644 --- a/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/JobManager.java +++ b/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/JobManager.java @@ -12,34 +12,30 @@ import org.scijava.Context; import cz.it4i.fiji.haas_java_client.HaaSClient; import cz.it4i.fiji.haas_java_client.JobState; import javafx.beans.value.ObservableValueBase; +import net.imagej.updater.util.Progress; public class JobManager { - - private Path workDirectory; - + private Collection<Job> jobs = new LinkedList<>(); - + private HaaSClient haasClient; private Context context; - - public JobManager(Path workDirectory, Context ctx) throws IOException { super(); this.context = ctx; this.workDirectory = workDirectory; context.inject(this); - Files.list(this.workDirectory).filter(p -> Files.isDirectory(p) && Job.isJobPath(p)) - .forEach(p -> { - try { - jobs.add(inject(new Job(p,this::getHaasClient))); - } catch (IOException e) { - e.printStackTrace(); - } - }); + Files.list(this.workDirectory).filter(p -> Files.isDirectory(p) && Job.isJobPath(p)).forEach(p -> { + try { + jobs.add(inject(new Job(p, this::getHaasClient))); + } catch (IOException e) { + e.printStackTrace(); + } + }); } @@ -48,27 +44,27 @@ public class JobManager { return job; } - public void startJob(Path path, Collection<Path> files) throws IOException { - jobs.add(new Job(path, files,this::getHaasClient)); + public void startJob(Path path, Collection<Path> files, Progress progress) throws IOException { + jobs.add(new Job(path, files, this::getHaasClient, progress)); } - + public Iterable<JobInfo> getJobsNeedingDownload() { - return ()->jobs.stream().filter(j->j.needsDownload()).map(j->new JobInfo(j)).iterator(); + return () -> jobs.stream().filter(j -> j.needsDownload()).map(j -> new JobInfo(j)).iterator(); } public Iterable<JobInfo> getJobs() { - return ()->jobs.stream().map(j->new JobInfo(j)).iterator(); + return () -> jobs.stream().map(j -> new JobInfo(j)).iterator(); } - + public void downloadJob(Long id) { - Iterator<Job> job =jobs.stream().filter(j->j.getJobId() == id).iterator(); + Iterator<Job> job = jobs.stream().filter(j -> j.getJobId() == id).iterator(); assert job.hasNext(); job.next().download(); - + } private HaaSClient getHaasClient() { - if(haasClient == null) { + if (haasClient == null) { haasClient = new HaaSClient(2l, 9600, 6l, "DD-17-31"); } return haasClient; @@ -77,8 +73,7 @@ public class JobManager { public static class JobInfo extends ObservableValueBase<JobInfo> { private Job job; - - + public JobInfo(Job job) { this.job = job; } @@ -94,20 +89,20 @@ public class JobManager { public boolean needsDownload() { return job.needsDownload(); } - + public String getStartTime() { return job.getStartTime().getTime().toString(); } - + public String getEndTime() { - return job.getEndTime().getTime().toString(); + return job.getEndTime() != null ? job.getEndTime().getTime().toString() : "N/A"; } - public void downloadData() { - job.download(); + public void downloadData(Progress progress) { + job.download(progress); fireValueChangedEvent(); } - + @Override public JobInfo getValue() { return this; diff --git a/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/RunWithHaaS.java b/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/RunWithHaaS.java index bbae55031ff42e984757b7ef06d5ca93d6cf83a2..d0c2f2f649dddb306ecb605921bdc8e2ddbe17a7 100644 --- a/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/RunWithHaaS.java +++ b/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/RunWithHaaS.java @@ -15,6 +15,8 @@ import org.scijava.plugin.Parameter; import org.scijava.plugin.Plugin; import net.imagej.ImageJ; +import net.imagej.ui.swing.updater.ProgressDialog; +import net.imagej.updater.util.Progress; /** * * @author koz01 @@ -26,10 +28,10 @@ public class RunWithHaaS implements Command { @Parameter private LogService log; - @Parameter(label="Work directory",persist=true) + @Parameter(label="Work directory",persist=true, style = "directory") private File workDirectory; - @Parameter(label="Data directory") + @Parameter(label="Data directory",persist=true, style = "directory") private File dataDirectory; @Parameter @@ -41,7 +43,7 @@ public class RunWithHaaS implements Command { public void run() { try { jobManager = new JobManager(getWorkingDirectoryPath(), context); - jobManager.startJob(getWorkingDirectoryPath(),getContent(dataDirectory)); + jobManager.startJob(getWorkingDirectoryPath(),getContent(dataDirectory), new ProgressDialog(null)); } catch (IOException e) { log.error(e); } diff --git a/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/ui/CheckStatusOfHaaSController.java b/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/ui/CheckStatusOfHaaSController.java index da719f99d121b1a3672737b450bbdb8bcb665222..b8119d974ea1b8aba7e8605c865408d33580d553 100644 --- a/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/ui/CheckStatusOfHaaSController.java +++ b/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/ui/CheckStatusOfHaaSController.java @@ -14,6 +14,7 @@ import javafx.scene.control.MenuItem; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.input.ContextMenuEvent; +import net.imagej.ui.swing.updater.ProgressDialog; public class CheckStatusOfHaaSController { @@ -37,7 +38,7 @@ public class CheckStatusOfHaaSController { } private void downloadData(ActionEvent event) { - jobs.getSelectionModel().getSelectedItem().downloadData(); + jobs.getSelectionModel().getSelectedItem().downloadData(new ProgressDialog(null)); } private void initMenu() { diff --git a/haas-java-client/src/main/java/cz/it4i/fiji/haas_java_client/HaaSClient.java b/haas-java-client/src/main/java/cz/it4i/fiji/haas_java_client/HaaSClient.java index 6f29d30ed86cbf75b2a077f92f263e095a95f7d2..9b74bd883a6cd06f0c6f927968c20cede3ac5bfd 100644 --- a/haas-java-client/src/main/java/cz/it4i/fiji/haas_java_client/HaaSClient.java +++ b/haas-java-client/src/main/java/cz/it4i/fiji/haas_java_client/HaaSClient.java @@ -10,6 +10,7 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; +import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.stream.Collectors; @@ -37,6 +38,7 @@ import cz.it4i.fiji.haas_java_client.proxy.TaskSpecificationExt; import cz.it4i.fiji.haas_java_client.proxy.UserAndLimitationManagementWsLocator; import cz.it4i.fiji.haas_java_client.proxy.UserAndLimitationManagementWsSoap; import cz.it4i.fiji.scpclient.ScpClient; +import cz.it4i.fiji.scpclient.TransferFileProgress; public class HaaSClient { @@ -89,6 +91,33 @@ public class HaaSClient { private String projectId; + private ProgressNotifier dummyNotifier = new ProgressNotifier() { + + @Override + public void setTitle(String title) { + } + + @Override + public void setItemCount(int count, int total) { + } + + @Override + public void setCount(int count, int total) { + } + + @Override + public void itemDone(Object item) { + } + + @Override + public void done() { + } + + @Override + public void addItem(Object item) { + } + }; + final static private Map<JobStateExt, JobState> WS_STATE2STATE; static { @@ -112,30 +141,60 @@ public class HaaSClient { } public long start(Iterable<Path> files, String name, Collection<Entry<String, String>> templateParameters) { + return start(files, name, templateParameters, dummyNotifier); + } + public long start(Iterable<Path> files, String name, Collection<Entry<String, String>> templateParameters, + ProgressNotifier notifier) { + notifier.setTitle("Starting job"); TaskSpecificationExt taskSpec = createTaskSpecification(name, templateId, templateParameters); JobSpecificationExt jobSpecification = createJobSpecification(name, Arrays.asList(taskSpec)); try { + String item; + String jobItem; SubmittedJobInfoExt job = getJobManagement().createJob(jobSpecification, getSessionID()); - System.out.printf("Created job: %d\n", job.getId()); + notifier.addItem(jobItem = String.format("Created job: %d\n", job.getId())); FileTransferMethodExt fileTransfer = getFileTransfer().getFileTransferMethod(job.getId(), getSessionID()); + List<Long> totalSizes = getSizes(files); + long totalSize = totalSizes.stream().mapToLong(l -> l.longValue()).sum(); + final long step = totalSize / 100; try (ScpClient scpClient = getScpClient(fileTransfer)) { - + final int[] index = { 0 }; + final long[] totalTransfered = { 0 }; for (Path file : files) { - System.out.println("Uploading file: " + file.getFileName()); + final long[] fileTransfered = { 0 }; + TransferFileProgress progress = new TransferFileProgress() { + + @Override + public long getMinimalDeltaForNotification() { + return step; + } + + @Override + public void dataTransfered(long bytesTransfered) { + fileTransfered[0] += bytesTransfered; + totalTransfered[0] += bytesTransfered; + notifier.setItemCount((int) (fileTransfered[0] >> 10), + (int) (totalSizes.get(index[0]) >> 10)); + notifier.setCount((int) (totalTransfered[0] >> 10), (int) (totalSize >> 10)); + } + }; + notifier.addItem(item = "Uploading file: " + file.getFileName()); String destFile = "'" + fileTransfer.getSharedBasepath() + "/" + file.getFileName() + "'"; - boolean result = scpClient.upload(file, destFile); - System.out.println(result ? "File uploaded." : "File not uploaded"); + boolean result = scpClient.upload(file, destFile, progress); + notifier.itemDone(item); if (!result) { throw new HaaSClientException("Uploading of " + file + " to " + destFile + " failed"); } + index[0]++; } } getFileTransfer().endFileTransfer(job.getId(), fileTransfer, getSessionID()); // submit job job = getJobManagement().submitJob((long) job.getId(), getSessionID()); - System.out.printf("Submitted job ID: %d\n", job.getId()); + notifier.itemDone(jobItem); + notifier.done(); return job.getId(); } catch (ServiceException | JSchException | IOException e) { throw new RuntimeException(e); @@ -160,11 +219,11 @@ public class HaaSClient { public JobState getState() { return WS_STATE2STATE.get(info.getState()); } - + public java.util.Calendar getStartTime() { return info.getStartTime(); }; - + public java.util.Calendar getEndTime() { return info.getEndTime(); }; @@ -184,29 +243,69 @@ public class HaaSClient { } } - public void download(long jobId, Path workDirectory) { + public void download(long jobId, Path workDir) { + download(jobId, workDir, dummyNotifier); + } + + public void download(long jobId, Path workDirectory, final ProgressNotifier notifier) { try { FileTransferMethodExt ft = getFileTransfer().getFileTransferMethod(jobId, getSessionID()); try (ScpClient scpClient = getScpClient(ft)) { - - for (String fileName : getFileTransfer().listChangedFilesForJob(jobId, getSessionID())) { + String[] files = getFileTransfer().listChangedFilesForJob(jobId, getSessionID()); + List<Long> fileSizes = getSizes(Arrays.asList(files).stream() + .map(filename -> ft.getSharedBasepath() + "/" + filename).collect(Collectors.toList()), + scpClient); + final long totalFileSize = fileSizes.stream().mapToLong(i -> i.longValue()).sum(); + + notifier.setTitle("Downloading"); + int[] idx = { 0 }; + final int[] totalDownloaded = { 0 }; + for (String fileName : files) { + final int[] fileDownloaded = { 0 }; fileName = fileName.replaceFirst("/", ""); Path rFile = workDirectory.resolve(fileName); if (!Files.exists(rFile.getParent())) { Files.createDirectories(rFile.getParent()); } String fileToDownload = "'" + ft.getSharedBasepath() + "/" + fileName + "'"; - scpClient.download(fileToDownload, rFile); - + String item; + notifier.addItem(item = fileName); + scpClient.download(fileToDownload, rFile, new TransferFileProgress() { + + @Override + public long getMinimalDeltaForNotification() { + return totalFileSize / 100; + } + + @Override + public void dataTransfered(long bytesTransfered) { + totalDownloaded[0] += bytesTransfered; + fileDownloaded[0] += bytesTransfered; + notifier.setCount((int) (totalDownloaded[0]), (int) (totalFileSize >> 10)); + notifier.setItemCount((int) (fileDownloaded[0]), (int) (fileSizes.get(idx[0]) >> 10)); + + } + }); + notifier.itemDone(item); + idx[0]++; } } getFileTransfer().endFileTransfer(jobId, ft, getSessionID()); + notifier.done(); } catch (IOException | JSchException | ServiceException e) { throw new HaaSClientException(e); } } + private List<Long> getSizes(List<String> asList, ScpClient scpClient) throws JSchException, IOException { + List<Long> result = new LinkedList<>(); + for (String lfile : asList) { + result.add(scpClient.size(lfile).get(0)); + } + return result; + } + private ScpClient getScpClient(FileTransferMethodExt fileTransfer) throws UnsupportedEncodingException, JSchException { byte[] pvtKey = fileTransfer.getCredentials().getPrivateKey().getBytes("UTF-8"); @@ -287,10 +386,19 @@ public class HaaSClient { return fileTransfer; } + private List<Long> getSizes(Iterable<Path> files) throws IOException { + List<Long> result = new LinkedList<>(); + for (Path path : files) { + result.add(Files.size(path)); + } + return result; + } + private String getSessionID() throws RemoteException, ServiceException { if (sessionID == null) { sessionID = authenticate(); } return sessionID; } + } diff --git a/haas-java-client/src/main/java/cz/it4i/fiji/haas_java_client/ProgressNotifier.java b/haas-java-client/src/main/java/cz/it4i/fiji/haas_java_client/ProgressNotifier.java new file mode 100644 index 0000000000000000000000000000000000000000..1b6c5df51e5eee07799511ecd466340eaf1c204d --- /dev/null +++ b/haas-java-client/src/main/java/cz/it4i/fiji/haas_java_client/ProgressNotifier.java @@ -0,0 +1,16 @@ +package cz.it4i.fiji.haas_java_client; + +public interface ProgressNotifier { + + public void setTitle(String title); + + public void setCount(int count, int total); + + public void addItem(Object item); + + public void setItemCount(int count, int total); + + public void itemDone(Object item); + + public void done(); +} diff --git a/java-scpclient/src/main/java/cz/it4i/fiji/scpclient/ScpClient.java b/java-scpclient/src/main/java/cz/it4i/fiji/scpclient/ScpClient.java index 41a8e8a999f6063a27583c85b86ab6a1dea3c3a3..a979d645c4c966e7f219642be4feb71dd5f93cf0 100644 --- a/java-scpclient/src/main/java/cz/it4i/fiji/scpclient/ScpClient.java +++ b/java-scpclient/src/main/java/cz/it4i/fiji/scpclient/ScpClient.java @@ -7,13 +7,18 @@ import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.List; +import java.util.stream.Collectors; import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelExec; +import com.jcraft.jsch.ChannelSftp; +import com.jcraft.jsch.ChannelSftp.LsEntry; import com.jcraft.jsch.Identity; import com.jcraft.jsch.JSch; import com.jcraft.jsch.JSchException; import com.jcraft.jsch.Session; +import com.jcraft.jsch.SftpException; import com.jcraft.jsch.UserInfo; public class ScpClient implements Closeable { @@ -21,11 +26,23 @@ public class ScpClient implements Closeable { private String username; private JSch jsch = new JSch(); private Session session; + private TransferFileProgress dummyProgress = new TransferFileProgress() { + + @Override + public long getMinimalDeltaForNotification() { + return 0; + } + + @Override + public void dataTransfered(long bytesTransfered) { + + } + }; public ScpClient(String hostName, String username, byte[] privateKeyFile) throws JSchException { init(hostName, username, new ByteIdentity(jsch, privateKeyFile)); } - + public ScpClient(String hostName, String username, Identity privateKeyFile) throws JSchException { super(); init(hostName, username, privateKeyFile); @@ -34,7 +51,7 @@ public class ScpClient implements Closeable { public ScpClient(String hostName, String userName, String keyFile, String pass) throws JSchException { Identity id = IdentityFile.newInstance(keyFile, null, jsch); try { - if(pass != null) { + if (pass != null) { id.setPassphrase(pass.getBytes("UTF-8")); } } catch (UnsupportedEncodingException e) { @@ -49,7 +66,11 @@ public class ScpClient implements Closeable { jsch.addIdentity(privateKeyFile, null); } - public boolean download(String lfile, Path rfile) throws JSchException, IOException { + public void download(String lfile, Path rFile) throws JSchException, IOException { + download(lfile, rFile, dummyProgress ); + } + + public boolean download(String lfile, Path rfile, TransferFileProgress progress) throws JSchException, IOException { Session session = connectionSession(); // exec 'scp -f rfile' remotely @@ -111,6 +132,7 @@ public class ScpClient implements Closeable { // read a content of lfile try (OutputStream fos = Files.newOutputStream(rfile)) { int foo; + long totalTransfered = 0; while (true) { if (buf.length < filesize) foo = buf.length; @@ -122,6 +144,11 @@ public class ScpClient implements Closeable { break; } fos.write(buf, 0, foo); + totalTransfered += foo; + if(totalTransfered >= progress.getMinimalDeltaForNotification()) { + progress.dataTransfered(totalTransfered); + totalTransfered = 0; + } filesize -= foo; if (filesize == 0L) break; @@ -146,6 +173,10 @@ public class ScpClient implements Closeable { } public boolean upload(Path file, String rfile) throws JSchException, IOException { + return upload(file, rfile,dummyProgress); + } + + public boolean upload(Path file, String rfile, TransferFileProgress progress) throws JSchException, IOException { Session session = connectionSession(); @@ -186,12 +217,18 @@ public class ScpClient implements Closeable { } byte[] buf = new byte[getBufferSize()]; // send a content of lfile + long transfered = 0; try (InputStream fis = Files.newInputStream(file)) { while (true) { int len = fis.read(buf, 0, buf.length); if (len <= 0) break; out.write(buf, 0, len); // out.flush(); + transfered += len; + if(transfered >= progress.getMinimalDeltaForNotification()) { + progress.dataTransfered(transfered); + transfered = 0; + } } } // send '\0' @@ -209,8 +246,28 @@ public class ScpClient implements Closeable { return true; } + @SuppressWarnings("unchecked") + public List<Long> size(String lfile) throws JSchException, IOException { + Session session = connectionSession(); + + // exec 'scp -f rfile' remotely + Channel channel = session.openChannel("sftp"); + + try { + channel.connect(); + return ((List<LsEntry>)((ChannelSftp) channel).ls(lfile)).stream().map(atr -> atr.getAttrs().getSize()) + .collect(Collectors.toList()); + + } catch (SftpException e) { + e.printStackTrace(); + } finally { + channel.disconnect(); + } + return null; + } + private int getBufferSize() { - return 1024*1024; + return 1024 * 1024; } private Session connectionSession() throws JSchException { @@ -290,7 +347,7 @@ public class ScpClient implements Closeable { @Override public void close() { - if ( session != null && session.isConnected()) { + if (session != null && session.isConnected()) { session.disconnect(); session = null; } diff --git a/java-scpclient/src/main/java/cz/it4i/fiji/scpclient/TransferFileProgress.java b/java-scpclient/src/main/java/cz/it4i/fiji/scpclient/TransferFileProgress.java new file mode 100644 index 0000000000000000000000000000000000000000..1e0f9632fe1e88bffec552c31938903d8360e723 --- /dev/null +++ b/java-scpclient/src/main/java/cz/it4i/fiji/scpclient/TransferFileProgress.java @@ -0,0 +1,6 @@ +package cz.it4i.fiji.scpclient; + +public interface TransferFileProgress { + long getMinimalDeltaForNotification(); + void dataTransfered(long bytesTransfered); +} diff --git a/java-scpclient/src/test/java/TestSCP.java b/java-scpclient/src/test/java/TestSCP.java index 070855d2b08e27821c87b45b64e5570080a86d54..bc70bc6d3e9336310a6e7650a3c7fe02ab3a1462 100644 --- a/java-scpclient/src/test/java/TestSCP.java +++ b/java-scpclient/src/test/java/TestSCP.java @@ -13,7 +13,10 @@ public class TestSCP { public static void main(String[] args) throws JSchException, IOException { try(ScpClient scp = new ScpClient("salomon.it4i.cz", "koz01", "/home/koz01/.ssh/it4i_rsa-np", null)) { - System.out.println( scp.upload(Paths.get("/home/koz01/Work/vyzkumnik/fiji/work/aaa/spim-data/exampleSingleChannel(9).czi"), "'/home/koz01/exampleSingleChannel(9).czi'")); +// System.out.println( scp.upload( +// Paths.get("/home/koz01/Work/vyzkumnik/fiji/work/aaa/spim-data/exampleSingleChannel(9).czi"), "'/home/koz01/exampleSingleChannel(9).czi'")); + System.out.println( scp.size("/home/koz01/exampleSingleChannel(9).czi")); + } }