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

我应该为“.thrift”-file定义什么样的服务,以便稍后在我的程序中使用它?

此文件传输应位于客户端和服务器之间,它应该“部分”。

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; } 

}

您的代码对我来说并不是那么糟糕(未经过测试),并且没有太大的变化。

怎么样

 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); } 

如果需要,可以容易地扩展FileChunk结构,例如为了返回附加元数据,例如总大小(特别是如果大小随时间增长/缩小),剩余字节,关于数据格式的指示等。 您不必这样做,因为如果以后需要这样做,您可以轻松扩展界面。 味道很重要。