Получить позицию на файловом канале
У меня есть класс, который копирует один файл из одной папки в другую:
public class Foo extends JFrame{
Timer t;
FileChannel inp = null,
outp= null;
File sourceFile = new File("C:/movies/movie.mkv"),
destFile = new File("C:/test/movie.mkv");
long rec = 0;
long size;
LayoutManager manager = new MigLayout();
public void createUI(){
JPanel panel = new JPanel();
JButton copyFile = new JButton("Copy file");
JButton btn = new JButton("Start function");
JButton stop = new JButton("Stop function");
panel.setLayout(manager);
panel.add(btn);
panel.add(copyFile,"wrap");
panel.add(stop);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setContentPane(panel);
this.setVisible(true);
this.setSize(400,400);
this.pack();
btn.addActionListener((e)->{
try {
inp = new FileInputStream(sourceFile).getChannel();
outp = new FileOutputStream(destFile).getChannel();
size = inp.size();
outp.transferFrom(inp,0,size);
} catch (Exception e2) {
// TODO Auto-generated catch block
System.out.println("FIle not found");
return;
}
t = new Timer(100,i->{
try {
rec = outp.position();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
rec = 0;
}
finally{
System.out.println("Position in file:"+rec);
}
});
t.start();
});
}
public static void main(String[] args) {
SwingUtilities.invokeLater(()->new Foo().createUI());
}
}
Теперь у меня есть таймер Swing, который каждые 100 мс выводит позицию в файле.
То, что я на самом деле пытаюсь сделать, это дать пользователю знать, сколько файла скопировано. Проблема в том, что каждые 100 мс число, которое выводится в моей консоли, равно "Положение в файле:126089692".
Я хотел бы получить объяснение, если это возможно.
Спасибо за ваше время
3 ответа
Я нашел в https://docs.oracle.com/javase/8/docs/api/:
public abstract long transferFrom(ReadableByteChannel src,
long position,
long count)
throws IOException-
"... Этот метод не изменяет позицию этого канала..."
Может быть, поэтому вы видите то же значение (я не проверял).
Попробуйте заменить:
rec = outp.position();
от
rec = inp.position();
Это потому, что вы сначала копируете весь файл (outp.transferFrom(inp,0,size);
), а затем запускает таймер - пока работа уже сделана. Попробуйте запустить таймер до фактической передачи данных.
Метод TransferFrom не выполняется асинхронно. Это уже закончено, когда ваш таймер запускается.
Попробуйте переместить часть try..catch (передача файла) в собственный поток, запустите сначала таймер, а затем поток передачи.
И кстати: интервал в 100 мс слишком быстр для графического интерфейса. Увеличение его на все секунды или полсекунды более чем достаточно.