Basics - reading/writing remote files using Java
Asked Answered
A

4

9

I started with requirement of reading and writing files in from/in a directory on a remote Ubuntu machine.

First, I wrote a Java program that could read,write files from a shared folder on a remote Windows machine i.e on a LAN. Here, something like this works on my(local) Windows machine :

File inputFile = new File(
                "\\172.17.89.76\EBook PDF");/*ignore the syntax errors, the loc is just for the idea*/

Now when I consider a remote Ubuntu machine, obviously I cannot do something like this as the machine is not on the LAN(I'm not sure if that can be done even if it is on the LAN!). Hence, I tried following approaches :

  1. Using Jsch, establishing the trust between two machines(local - remote Linux , remote Linux - remote Linux) and file writing using sftp.(done)
  2. Running sockets on the two machines - one sender, one receiver(both Java)(done)
  3. Attempting to achieve I/O alike the code snippet for Windows (LAN) machines(not achieved)

While doing all these, I had many queries, read many posts etc. and I felt that I'm missing something on the fundamentals :

  • Some sort of trust-building(between two machines) utility will be required to achieve IO. But finally, I want to write a code like the snippet given, irrespective of the machines, network etc.
  • The Jsch solution and the others suggested(usage of http, ftp etc. over URL) finally are using some services that are running on the remote machine. In other words, it is NOT THAT Java IO is being used to access the remote file system - this doesn't appeal to me as I'm relying on services rather than using good-old I/O.
  • Samba, SSHFS too popped onto the scene, only to add to my confusion. But I don't see them as the solutions to my objective !

To reiterate, I want to write a code using Java I/O(either plain or nio, both are fine) which simply can read, write remote files without using services over protocols like ftp, http etc. or socket sender-receiver model. Is my expectation valid?

  • If not, why and what is the best I can do to read/write remote files using Java?
  • If yes, how to achieve the same !

P.S : Please comment in case I need to elaborate to pose my question accurately !

Annulose answered 27/9, 2012 at 6:36 Comment(6)
I'm not sure this will help, but you could take a look at Apache VFSZonazonal
Java is dependent at some level on the OS to do the IO - even the good old IO uses these - so a little unclear what your question emphasizes.Hurdygurdy
@Zonazonal I checked it but I don't think my requirement has to do anything with the file 'type'; also, it supports file reading over FTP,SFTP,HTTPS etc. which I don't wish to use. Thanks and regards !Annulose
@Hurdygurdy I want to run Java code on Machine1 which creates a java.io.File object pointing to a file on Machine2. Some possibilities : 1. Machine1 and Machine2 can be Windows-Linux, Windows-Windows, Linux-Linux 2. Can be on different networks(not necessarily on LAN)Annulose
I think your best, out of box solution, if you don't want to download the file locally is some kind of of network share, something like smbZonazonal
A good while ago i used RMI to implement remote stream classes allowing regular stream piping once the target machine had created a handle/stub for the remote stream. That ofcourse requires some kind of service to run on the target machine. I used that to stream GB of data from WebStart clients to a central file server.Rhizome
P
6

If you want to access a filesystem on a remote computer, then this computer has to make his filesystem available with a service. Such a service is typically a background job, which handles incoming requests and returns a response, e.g. for authentication, authorization, reading and writing. The specification of the request/response pattern is called a protocol. Well known protocols are SMB (or SAMBA) on Windows or NFS on UNIX/LINUX. To access such a remote service you mount the remote filesystem on the level of the operating system and make it available locally as a drive on Windows or as mount point on UNIX.

Then you can access the remote file system from your Java program like any local file system.

Of course it is also possible to write your own file service provider (with your own protocol layer) and run it on the remote machine. As transport layer for such an endeavor sockets (TCP/IP) can be used. Another good transport layer would be the http protocol, e.g. with a restful service or something based on WebDav.

Polacre answered 5/10, 2012 at 21:6 Comment(0)
C
13

To answer your question - No, your expectation isn't valid.

Retrieving files from a remote server is inherently reliant on the services running on that server. To retrieve a file from a remote server, the remote server needs to be expecting your request for a file.

The cases you listed in your question (using jsch and sftp, using a sender and receiver Java sockets) that you have achieved already, are essentially the same as this:

File inputFile = new File(
            "\\172.17.89.76\EBook PDF");

The only difference is that Java is using the native os's built in support for reading from a windows style share. The remote windows machine has a sharing service running on it (just like Samba on linux, or a java socket program) waiting for your request.

From the Java API docs on File (http://docs.oracle.com/javase/6/docs/api/java/io/File.html)

The canonical pathname of a file that resides on some other machine and is accessed via a remote-filesystem protocol such as SMB or NFS ...

So essentially "Good old Java I/O" is more or less just a wrapper over some common protocols.

To answer the second part of your question (what is the best I can do to read/write remote files using Java?), that depends on what remote system you are accessing and, more importantly, what services are running on it.

In the case of your target remote machine being an Ubuntu machine, I would say the best alternative would be to use Jsch. If your target machine can be either a windows machine or a linux machine, I would probably go for running Java sockets on the two machines (obviously dependant on whether you have access to installing your app on the remote machine).

Generally speaking, go with the common lowest denominator between your target systems (in terms of file sharing protocols).

Carpio answered 10/10, 2012 at 12:25 Comment(0)
P
6

If you want to access a filesystem on a remote computer, then this computer has to make his filesystem available with a service. Such a service is typically a background job, which handles incoming requests and returns a response, e.g. for authentication, authorization, reading and writing. The specification of the request/response pattern is called a protocol. Well known protocols are SMB (or SAMBA) on Windows or NFS on UNIX/LINUX. To access such a remote service you mount the remote filesystem on the level of the operating system and make it available locally as a drive on Windows or as mount point on UNIX.

Then you can access the remote file system from your Java program like any local file system.

Of course it is also possible to write your own file service provider (with your own protocol layer) and run it on the remote machine. As transport layer for such an endeavor sockets (TCP/IP) can be used. Another good transport layer would be the http protocol, e.g. with a restful service or something based on WebDav.

Polacre answered 5/10, 2012 at 21:6 Comment(0)
B
4

We used sshfs. You can add to /etc/fstab the line:

sshfs#user@remoteAddress:remoteDir /mnt/ssh fuse defaults 0 0

and then mount /mnt/ssh

Busywork answered 5/10, 2012 at 21:32 Comment(2)
If you have file /home/user/remoteDir/dir/file.txt or remote machine you can mount it to your machine. You will access it by: /mnt/ssh/dir/file.txt from your local machine (remote mount point is /home/user/remoteDir/). For test install sshfs and call sshfs user@hostname:remoteDir /mnt/ssh. From java code run simple new File("/home/user/remoteDir/dir/file.txt")Busywork
Oh ! So it is roughly similar to accessing a mounted network drive and/or a shared folder. I'll try this one - thanks !Annulose
H
0

I think RMI might be the solution, you could set up a server an RMI server on the machine you want to connect to, and use your machine a the client.

I would give the client a path to the file this will be sent to the server, the server could then read in the file as bytes and sent the file back to the client.

Hectorhecuba answered 5/10, 2012 at 23:27 Comment(3)
Are you hinting at the usage of Socket - two programs running, one sender,one receiver ? If yes, I have tried it earlier and I do not intend to use it.Annulose
I'm not sure about sockets, RMI (remote method invocation) is the java version of corba I think.Hectorhecuba
@Hectorhecuba it is not so much the Java version of Corba but can utilize Corba under the hood.Rhizome

© 2022 - 2024 — McMap. All rights reserved.