Получить позицию на файловом канале

У меня есть класс, который копирует один файл из одной папки в другую:

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 мс слишком быстр для графического интерфейса. Увеличение его на все секунды или полсекунды более чем достаточно.

Другие вопросы по тегам