Filesystems 从S3对象存储读取文件并将其写入winSCP

Filesystems 从S3对象存储读取文件并将其写入winSCP,filesystems,sftp,nio,bytebuffer,filechannel,Filesystems,Sftp,Nio,Bytebuffer,Filechannel,我正试图通过SFTP连接使用winSCP从远程文件系统中放入和读取文件。文件系统的叶节点是s3对象存储,其中包含文件(例如:xyz.txt)。 下面是文件通道类的重写方法 XYZFileSystemProvider public class XYZFileSystemProvider extends FileSystemProvider { @Override public FileChannel newFileChannel(Path path, Set<? ex

我正试图通过SFTP连接使用winSCP从远程文件系统中放入和读取文件。文件系统的叶节点是s3对象存储,其中包含文件(例如:xyz.txt)。 下面是文件通道类的重写方法

XYZFileSystemProvider

public class XYZFileSystemProvider extends FileSystemProvider {
    @Override
        public FileChannel newFileChannel(Path path, Set<? extends OpenOption> options, FileAttribute<?>... attrs)
                throws IOException {
            // TODO Auto-generated method stub

            Collection<XYZOptions.OpenMode> modes = XYZOptions.OpenMode.fromOpenOptions(options);
            if (modes.isEmpty()) {
                modes = EnumSet.of(XYZOptions.OpenMode.Read, MFEOptions.OpenMode.Write);
            }
            // TODO: process file attributes
            return new XYZFileSystemChannel(path, modes);
        }
}
公共类XYZFileSystemProvider扩展FileSystemProvider{
@凌驾
公共文件通道newFileChannel(路径路径,设置…属性)
抛出IOException{
//TODO自动生成的方法存根
收集模式=XYZOptions.OpenMode.fromOpenOptions(选项);
if(modes.isEmpty()){
模式=枚举集(XYZOptions.OpenMode.Read,MFEOptions.OpenMode.Write);
}
//TODO:进程文件属性
返回新的XYZFileSystemChannel(路径、模式);
}
}
XYZFileSystemChannel

public class XYZFileSystemChannel extends XYZRemotePathChannel{

    public XYZFileSystemChannel(XYZPath p, Collection<XYZOptions.OpenMode> modes) throws IOException {
        this(Objects.requireNonNull(p, "No target path").toString(), p.getFileSystem(), modes);
    }

    public XYZFileSystemChannel(String remotePath, XYZFileSystem fs, Collection<XYZOptions.OpenMode> modes) throws IOException {
        super(remotePath, fs, true, modes);
    }

}
公共类XYZFileSystemChannel扩展了XYZRemotePathChannel{
公共XYZFileSystemChannel(XYZP路径,收集模式)引发IOException{
这(Objects.requirennull(p,“无目标路径”).toString(),p.getFileSystem(),modes);
}
公共XYZFileSystemChannel(字符串远程路径、XYZFileSystem fs、收集模式)引发IOException{
super(远程路径、fs、true、模式);
}
}
XYZRemotePathChannel

公共类XYZRemotePathChannel扩展了FileChannel{
私有AmazonS3Component getAmazonS3Instance(){
返回SpringContext.getBean(AmazonS3Component.class);
}
私有最终字符串路径;
私人最终收集模式;
私有最终布尔closeOnExit;
专用XYZFileSystem文件系统;
专用最终AtomicLong posTracker=新AtomicLong(0L);
公共静态最终设置读取模式=
Collections.unmodifiableSet(EnumSet.of(XYZOptions.OpenMode.Read));
私有最终对象锁=新对象();
private final AtomicReference blockingThreadHolder=新的AtomicReference(null);
公共XYZRemotePathChannel(字符串路径、XYZFileSystem文件系统、布尔closeOnExit、,
收集模式)引发IOException{
this.path=ValidateUtils.checkNotNullAndNotEmpty(路径,“未指定远程文件路径”);
this.modes=Objects.requirennull(modes,“未指定通道模式”);
this.closeOnExit=closeOnExit;
this.fileSystem=文件系统;
}
@凌驾
公共整数读取(ByteBuffer dst)引发IOException{
//TODO自动生成的方法存根
debug(“dst的位置是:{}”,dst.Position());
debug(“读取文件的字节:{}”,dst);
//这里需要执行一些代码,以便读取dst并发送从s3存储接收的文件字节
return(int)doRead(Collections.singletonList(dst))-1;
}
受保护的长数据读取(列表缓冲区,长位置)引发IOException{
debug(“读取缓冲区列表:{}和位置:{}”的文件字节,缓冲区,位置);
重新打开(读取模式);
已同步(锁定){
布尔完成=假;
布尔eof=假;
long curPos=(位置>=0L)?位置:posTracker.get();
字节[]字节=新字节[(int)curPos];
试一试{
长totalRead=0;
beginblock();
String[]parts=this.path.toString().replaceFirst(“^/”,“).split(“/”);
串桶=零件[零件长度-2];
字符串文件名=零件[parts.length-1];
InputStream fileContent=getAmazonS3Instance().getFileFromBucket(bucket,文件名);
debug(“文件的内容:{}来自bucket:{}是:{}”,文件名,bucket,fileContent);
//这里需要执行一些代码来返回内容字节长度??
int fileLenght=fileContent.read(字节,1,(int)curPos);
debug(“读取文件内容后,文件长度为:{}”,fileLenght);
返回文件长度;
}最后{
如果(位置<0升){
后支架组(curPos);
}
封端(已完成);
}
}
}
私有void endBlocking(布尔完成)引发AsynchronousCloseException{
blockingThreadHolder.set(空);
完(已完);
}
私有void beginblock(){
begin();
blockingThreadHolder.set(Thread.currentThread());
}
@凌驾
公共文件通道位置(long newPosition)引发IOException{
//TODO自动生成的方法存根
debug(“设置文件的位置:{}”,newPosition);
如果(新位置<0升){
抛出新的IllegalArgumentException(“位置(“+this.path+”)非法文件通道位置:“+newPosition”);
}
重新打开(Collections.emptySet());
后置球拍设置(新位置);
归还这个;
}
私有重新打开(集合请求模式)引发IOException{
如果(!isOpen()){
抛出新的ClosedChannel异常();
}
if(通用实用程序大小(需求模式)>0){
用于(XYZOptions.OpenMode m:reqModes){
if(此模式包含(m)){
返回;
}
}
抛出新IOException(“重新打开”(+this.path+))当前通道模式(“+this.modes
+)不包含任何所需的:“+reqModes”;
}
}
}
XYZOptions

public class XYZOptions {

    enum OpenMode {
        Read, Write, Append, Create, Truncate, Exclusive;

        public static final Set<OpenOption> SUPPORTED_OPTIONS = Collections
                .unmodifiableSet(EnumSet.of(StandardOpenOption.READ, StandardOpenOption.APPEND,
                        StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE,
                        StandardOpenOption.CREATE_NEW, StandardOpenOption.SPARSE));

        public static Set<OpenMode> fromOpenOptions(Collection<? extends OpenOption> options) {
            if (GenericUtils.isEmpty(options)) {
                return Collections.emptySet();
            }

            Set<OpenMode> modes = EnumSet.noneOf(OpenMode.class);
            for (OpenOption option : options) {
                if (option == StandardOpenOption.READ) {
                    modes.add(Read);
                } else if (option == StandardOpenOption.APPEND) {
                    modes.add(Append);
                } else if (option == StandardOpenOption.CREATE) {
                    modes.add(Create);
                } else if (option == StandardOpenOption.TRUNCATE_EXISTING) {
                    modes.add(Truncate);
                } else if (option == StandardOpenOption.WRITE) {
                    modes.add(Write);
                } else if (option == StandardOpenOption.CREATE_NEW) {
                    modes.add(Create);
                    modes.add(Exclusive);
                } else if (option == StandardOpenOption.SPARSE) {
                    continue;
                } else {
                    throw new IllegalArgumentException("Unsupported open option: " + option);
                }
            }

            return modes;
        }
    }

}
公共类XYZOptions{
枚举OpenMode{
读、写、追加、创建、截断、独占;
公共静态最终集支持的\u选项=集合
.unmodifiableSet(枚举集)of(StandardOpenOption.READ、StandardOpenOption.APPEND、,
StandardOpenOption.create
public class XYZOptions {

    enum OpenMode {
        Read, Write, Append, Create, Truncate, Exclusive;

        public static final Set<OpenOption> SUPPORTED_OPTIONS = Collections
                .unmodifiableSet(EnumSet.of(StandardOpenOption.READ, StandardOpenOption.APPEND,
                        StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE,
                        StandardOpenOption.CREATE_NEW, StandardOpenOption.SPARSE));

        public static Set<OpenMode> fromOpenOptions(Collection<? extends OpenOption> options) {
            if (GenericUtils.isEmpty(options)) {
                return Collections.emptySet();
            }

            Set<OpenMode> modes = EnumSet.noneOf(OpenMode.class);
            for (OpenOption option : options) {
                if (option == StandardOpenOption.READ) {
                    modes.add(Read);
                } else if (option == StandardOpenOption.APPEND) {
                    modes.add(Append);
                } else if (option == StandardOpenOption.CREATE) {
                    modes.add(Create);
                } else if (option == StandardOpenOption.TRUNCATE_EXISTING) {
                    modes.add(Truncate);
                } else if (option == StandardOpenOption.WRITE) {
                    modes.add(Write);
                } else if (option == StandardOpenOption.CREATE_NEW) {
                    modes.add(Create);
                    modes.add(Exclusive);
                } else if (option == StandardOpenOption.SPARSE) {
                    continue;
                } else {
                    throw new IllegalArgumentException("Unsupported open option: " + option);
                }
            }

            return modes;
        }
    }

}