问题
I can not figure out how to transfer files using async and future. I have the code, when I run this code, getting of a files is working, but transfer a files don't work.
Server
package test3;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class server3 {
private static final int PORT = 1234;
private static final String FILE_NAME = "2.jpg";
private static class Storage {
private final AsynchronousFileChannel fileChannel;
private Future<Integer> writeOperation, readOperation;
private long positionWrite, positionRead;
long counter =0;
Storage() throws IOException {
fileChannel = AsynchronousFileChannel.open(Paths.get(FILE_NAME),
StandardOpenOption.CREATE,
StandardOpenOption.WRITE,
StandardOpenOption.READ);
}
void fileReadAndWrite(ByteBuffer buffer, SocketChannel socketChannel)
throws InterruptedException, ExecutionException, IOException {
try {
if (readOperation != null)
positionRead += readOperation.get(5, TimeUnit.SECONDS);
readOperation = fileChannel.read(buffer, positionRead);
buffer.flip();
socketChannel.write(buffer);
} catch (TimeoutException exc) {
close();
System.out.println("Read timeout");
}
}
void write(ByteBuffer buffer) throws InterruptedException, ExecutionException {
try {
if (writeOperation != null)
positionWrite += writeOperation.get(5, TimeUnit.SECONDS);
writeOperation = fileChannel.write(buffer, positionWrite);
} catch (TimeoutException exc) {
close();
System.err.println("Write timeout");
}
}
void close() {
try {
fileChannel.close();
} catch (IOException exc) {
exc.printStackTrace();
}
}
}
public static void main(String args[]) throws Exception {
Selector selector = Selector.open();
try (ServerSocketChannel serverSocketChannel = ServerSocketChannel.open()) {
serverSocketChannel.bind(new InetSocketAddress(PORT));
serverSocketChannel.configureBlocking(false);
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
selector.select();
Set<SelectionKey> keys = selector.selectedKeys();
Iterator<SelectionKey> iterator = keys.iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
if (key.isAcceptable()) {
SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_WRITE | SelectionKey.OP_READ,
new Storage());
System.out.println("isAcceptable");
}
if (key.isReadable()) {
System.out.println("isReadable");
SocketChannel socketChannel = (SocketChannel) key.channel();
Storage storage = (Storage) key.attachment();
ByteBuffer buffer = ByteBuffer.allocate(256);
int read = socketChannel.read(buffer);
if (read != -1) {
buffer.flip();
storage.write(buffer);
} else {
storage.close();
socketChannel.close();
}
}
if (key.isWritable()) {
Storage storage = (Storage) key.attachment();
SocketChannel socketChannel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
if (storage.fileChannel.size() >= storage.readOperation) {
storage.fileReadAndWrite(buffer, socketChannel);
} else {
storage.close();
socketChannel.close();
}
}
}
iterator.remove();
}
}
}
}
Client
package test.test1;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.*;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
public class client_test1 {
private static final int PORT = 1234;
private static final String HOST = "localhost";
private static final String FILE_NAME = "3.jpg";
private static InetSocketAddress serverAddress = new InetSocketAddress(HOST, PORT);
public static void main(String[] args) {
try (SocketChannel socketChannel = SocketChannel.open(serverAddress)) {
try (FileChannel fileChannel = FileChannel.open(
Paths.get(FILE_NAME), StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
fileChannel.transferFrom(socketChannel, 0, Long.MAX_VALUE);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
If the channel is ready to receive new files, run this line if (key.isWritable())
. This line if (storage.counter != 30)
is wrong. This line call until the file is transferred. I don't understand how to transfer a file. Help, please.
来源:https://stackoverflow.com/questions/50112763/transfer-a-file