服务器/客户端之间的文件传输

4

我应该为“.thrift”文件定义哪种服务,以便稍后在我的程序中使用它?

这个文件传输应该在客户端和服务器之间进行,并且应该是“部分的”。

StreamFileService.thrift:

struct FileChunk {
1: binary data
2: i64 remaining
}

service StreamFileService {    
FileChunk getBytes(1:string fileName, 2: i64 offset, 3: i32 size);    
}

StreamFileClient.java:

public class StreamFileClient {
private int fileChunkSize = 16;
private String filePath;

public String getFilePath() {
    return filePath;
}

public void setFilePath(String filePath) {
    this.filePath = filePath;
}

private void invoke() {

    try {

        TTransport theClientTransport = new TFramedTransport(new TSocket(
                "127.0.0.1", 7911));
        TProtocol theProtocol = new TBinaryProtocol(theClientTransport);
        StreamFileService.Client theClient = new StreamFileService.Client(
                theProtocol);
        theClientTransport.open();

        filePath = "/home/output/output.pdf";
        File theFile2 = new File(filePath);
        theFile2.createNewFile();
        FileInputStream stream = new FileInputStream(theFile2);
        long currentPosition = 0;

        FileChannel theFileChannel = stream.getChannel();
        boolean again = true;

        do {
            FileChunk chunk2 = theClient.getBytes(filePath,
                    currentPosition, fileChunkSize);
            currentPosition += fileChunkSize;

            theFileChannel.write(chunk2.data);

            if (chunk2.remaining == 0)
                again = false;

        } while (again);
        stream.close();

    } catch (TTransportException e) {
        e.printStackTrace();
    } catch (TException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

public static void main(String[] args) {
    StreamFileClient theClient = new StreamFileClient();

    theClient.invoke();

}

}

StreamFileServer.java:

public class StreamFileServer {

private void start() {
    try {

        TNonblockingServerTransport theServerSocket = new TNonblockingServerSocket(
                7911);
        StreamFileService.Processor theProcessor = new StreamFileService.Processor(
                new StreamFileServiceImpl());
        TServer theServer = new TNonblockingServer(
                new TNonblockingServer.Args(theServerSocket)
                        .processor(theProcessor));
        System.out.println("Server starting on port 7911...");

        theServer.serve();

    } catch (TTransportException e) {
        e.printStackTrace();
    }

}

public static void main(String[] args) {
    StreamFileServer theFileServer = new StreamFileServer();
    theFileServer.start();
}

}

StreamFileServiceImpl:

  public class StreamFileServiceImpl implements StreamFileService.Iface {

public FileChunk getBytes(String filePath, long offset, int size)
        throws TException {

    File theFile = new File("/home/input/kl_12.pdf");
    FileChunk chunk = new FileChunk();

    try {

        FileOutputStream stream = new FileOutputStream(theFile);

        MappedByteBuffer buffer = stream.getChannel().map(
                FileChannel.MapMode.READ_ONLY, offset, size);
        chunk.data = buffer;
        chunk.remaining = stream.getChannel().size() - offset - size;
        stream.close();

    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return chunk;
}

}


你能试着改进一下你的问题吗?"Partly" 是什么意思呢?也许可以描述一下你已经尝试过什么?以目前的格式,该问题很可能会被关闭,无法得到答案。 - JensG
我正在尝试使用Thrift实现服务器到客户端的文件传输。 "部分"意味着不是一次性传输文件的全部长度,而是两次或三次传输。 - Dakatabe
这是我的服务的样子(StreamFileService.thrift):typedef binary binarservice StreamFileService {binar getBytes(1:string fileName);} - Dakatabe
请不要将代码放入评论中。您可以自己看到它完全无法阅读。请将其编辑到您的问题中。这里还没有足够的信息来回答您的问题。 - user207421
这个“部分”文件传输会对客户端造成什么影响? - Dakatabe
显示剩余4条评论
1个回答

6

你的代码看起来还不错(未测试),没有太多需要改动的地方。

你觉得怎么样?

typedef binary binar
service StreamFileService {    
   binar getBytes(1:string fileName, 2: i64 offset, 3: i32 size);    
   i64 getSize(1:string fileName)
}

我也会返回一个包含字节的结构体,但这更多地是我的个人意见。
struct FileChunk {
  1: binary data
  2: i64 remaining
}

service StreamFileService {    
   FileChunk getBytes(1:string fileName, 2: i64 offset, 3: i32 size);    
}
< p >如果需要,可以轻松扩展 FileChunk 结构,例如为了返回其他元数据,如总大小(特别是如果大小随时间增长/缩小),剩余字节数,有关数据格式的指示等。如果以后需要,您无需这样做,因为您可以轻松扩展接口。这是个人喜好问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接