views:

220

answers:

1

Hello,

I am trying to pull the latest file out of a directory, which is located on a sftp server. The way I do it right now is more or less:

public FileObject getLatestFile(String directory) throws FileSystemException {
    FileObject fo = fsManager.resolveFile(this.host+directory, fsOptions);
    FileObject latestFile = null;
    long max  = 0;
    fo.getContent().
    for (FileObject fob : fo.getChildren()){
        if (fob.getContent().getLastModifiedTime() > max) {
            max = fob.getContent().getLastModifiedTime();
            latestFile = fob;
        }
    }
    return latestFile;
}

The problem with this approach is that I am basically downloading every file in the given directory, everytime the method is called.

Is there any better way to do this?

+2  A: 

You are not downloading the content.

If you look in the source code:

/**
 * Returns the file's content.
 */
public FileContent getContent() throws FileSystemException
{
    synchronized (fs)
    {
        attach();
        if (content == null)
        {
            content = new DefaultFileContent(this, getFileContentInfoFactory());
        }
        return content;
    }
}

calling getContent just returns an object implementation and getting attributes like size, modified dates basically it is extracted when exploring the remote folder(every protocol is different, but for example when you list an FTP folder you get all the files attributes).

For SFTP this what you actually call :

protected long doGetLastModifiedTime() throws Exception
{
    if (attrs == null
            || (attrs.getFlags() & SftpATTRS.SSH_FILEXFER_ATTR_ACMODTIME) == 0)
    {
        throw new FileSystemException(
                "vfs.provider.sftp/unknown-modtime.error");
    }
    return attrs.getMTime() * 1000L;
}

I agree, naming is confusing and it implies that content is retrieved when getContent is invoked but actually is not.

adrian.tarau
cool, nice analysis. Still the code is slow, which makes me guess roundtrips are to blame.Thanks.
thanos panousis
If you look in SftpFileObject.doListChildrenResolved, every child has its attributes populated at creation time : ((SftpFileObject) FileObjectUtils.getAbstractFileObject(fo)).setStat(stat.getAttrs()); so we can exclude the possibility of retrieving file attributes per item(sfpt ls command already gets that).It would be interesting to see why it is slow, maybe you can do a tcpdump/Wireshark(Linux tools) to see if make additional connections.
adrian.tarau