Unsolved Qt fails to copy file on ubuntu.
-
@jsulm Thank you.
I mean USB Flash Disk.
No matter I use QFile::copy or system, it have the same result. It's often empty.I want to copy it to a USB Flash Disk, and open it on a different computer.
-
@Qingshui-Kong Does it work if you do it manually in a terminal? Just to make sure it is not an issue with access rights.
-
Hi
Also, just to be 100% sure.
You do unmount the USB stick after copy to it?
From the File Manager. -
@jsulm Yes, it works, if I do it manually in a terminal.
-
@mrjj No, I don't unmount it. Even I do it manunally in a terminal, I don't unmount it.
Because the my software is fullscreen, I can't unmount it. -
-
If behaviour happens with
system()
as well then it is not a Qt/QFile::copy()
issue. -
You don't check the return results of
system()
&QFile::copy()
. -
You have read the
QFile::copy()
docs where it says:
Note that if a file with the name newName already exists, copy() returns false (i.e. QFile will not overwrite it).
haven't you?
-
Do you know it's empty via
ls -l
or viacat
? -
The fact that you say "It's often empty" implies to me it could be a timing issue. How long do you allow to elapse between doing the copy and trying to access the data?
-
I find it hard to believe that
system("cp ...")
does not work but doing thecp
from a shell does.... -
If you really find you have to, have a look at
man sync
for forcing a flush.
-
-
@JonB Thank you. I will check it.
-
@JonB
Thank you very much!I think I have solved the issue by using sync to force a flush.
Maybe you think it hard to believe that system("cp ...") does not work but doing the cp from a shell does....
But it is true. I tested more then ten times for each methods. But I don't know the reason. Could you tell me that, if you know?Thanks again.
-
@Qingshui-Kong said in Qt fails to copy file on ubuntu.:
But I don't know the reason. Could you tell me that, if you know?
This is your hint:
@mrjj said in Qt fails to copy file on ubuntu.:You do unmount the USB stick after copy to it?
On Linux you most often run
extX
kind of a filesystem, which is a journaling file system. This means that writes, moves and w/e else operations you do, don't happen synchronously (i.e. immediately when you issue it). You can think of the journal as kind of transaction processing. You want that because file operations are usually consisting of many small actual writes to the nonvolatile memory and if something interrupts any of them you don't want your filesystem to be gone for good. This however implies that the journal has to be flushed, and if you don't do it explicitly for many devices it is done implicitly when youumount
them. Since you don'tumount
your USB, the journal is never flushed and no data is in actuality written on the stick.sync
does exactly that - you explicitly flush the journal, thus even when you don'tumount
the device it does contain the actual data. As an advice: always unmount your devices. -
@kshegunov Thank you very much for telling me the details. Now I know the reason why I can solve the issue by using sync.
I can't umount the device, because my application is showing fullscreen. So I can't operate the system. I think I can add a function to my software to umount the device.
But I still wonder why doing the cp from a shell works even though I don't umount the device.
-
Maybe you think it hard to believe that system("cp ...") does not work but doing the cp from a shell does....
But it is true. I tested more then ten times for each methods. But I don't know the reason. Could you tell me that, if you know?But I still wonder why doing the cp from a shell works even though I don't umount the device.
Sorry, but I simply do not believe that sitting in a shell and executing a
cp
will behave any differently than sitting a program and executingsystem("cp ...")
! (Assuming same permissions etc.) The shell itself is a program, and when it executes/bin/cp
for you it will be using code not dissimilar (in terms of behaviour) from goingsystem("cp")
.You still did not put in the necessary error checking, and reading of stderr in case something appears there, when your code goes
system("cp ...")
with your arguments. So there is a chance that thecp
you execute from your code is not doing what you think.As for why
cp
works for you at all: there is a chance it executes afsync(2)
for you on this particular file, though frankly I would be surprised if it did. -
@JonB One another possibility for different behaviour: different environments in a terminal and when calling cp with system().
-
@jsulm
Possibly true, but can you name anything in the environment which is going to make a command-line-invokedcp
behave the slightest bit differently wrt syncing to a USB device? Because I can't :) Just in case, perhaps the OP should test running his app from the terminal instead of from Qt Creator if that's what he's currently doing... -
@JonB I can't as well, this is simply something that could make a difference even if I can't say exactly what it could be.
-
Hi,
How are you handling the device ?
Are you mounting manually ?
Is your application responsible for that part too ?
Do you have multiple devices and not writing on the same by accident ? -
@SGaist As I said, I didn't mount or unmount manually.
And I only have one ubuntu system and one USB disk. -
@jsulm @mrjj @JonB @kshegunov @SGaist
Thank you all!
I think maybe I should learn more knowledge about Linux system. -
@Qingshui-Kong
Yes and no! The question you are asking about the behaviour of a mounted USB drive, and seeming to need to either unmount orsync
/fsync()
, is actually a nasty area! I too would not be sure of behaviour, so it's very understandable that you are unsure :) -
@JonB
OK. Thank you! I use sync to solve the problem. -
@Qingshui-Kong
Yes, that seems OK. It forces the OS to flush the pending content to the USB file, without which your problem seems to occur, so it is understandable.Running
sync
on its own asks the OS to flush all file systems, which technically you do not need. If you wish to improve on this, from a terminal runman sync
to read its syntax. There you can see that if you specify the individual USB file path as an argument it will only sync/flush that file system, which is all you need.