QFile bytesAvailable() returns always 0
-
Hello everyone,
I'm trying to write a simple sequential program controlling an embedded device (through a device file "/dev/usbtmc0" in Linux). I don't want to use signals and slots. The device doesn't return new line or carriage return. And here comes the problem ... My code is this (in a separate thread):void osc::run(){ QString line; dev_file_stream.setDevice(&dev_file); dev_file_stream << "*IDN?\n"; dev_file_stream.flush(); qDebug() << "waiting reply ..."; dev_file.waitForReadyRead(-1); qDebug() << "reply received!"; quint64 bytes = dev_file.bytesAvailable(); qDebug() << "bytes: " << bytes; line = dev_file_stream.read(bytes); //line = dev_file_stream.readLine(); qDebug() << "line: " << line; }If I use this code, bytesAvailable( ) returns always 0.
If I use readLine( ), reading becomes terribly slow (5 or 6 seconds) probably because the reply doesn't have a '\n' or a '\r'.
If I use readLine(10), reading becomes fast but I'm missing chars because the replies are of different length (20, 30, 40, etc).Any help is appreciated!
Regards,
L. B.p.s. I've been struggling with this problem for years, and have always been forced to write complex signal-slot programs.
-
Hello everyone,
I'm trying to write a simple sequential program controlling an embedded device (through a device file "/dev/usbtmc0" in Linux). I don't want to use signals and slots. The device doesn't return new line or carriage return. And here comes the problem ... My code is this (in a separate thread):void osc::run(){ QString line; dev_file_stream.setDevice(&dev_file); dev_file_stream << "*IDN?\n"; dev_file_stream.flush(); qDebug() << "waiting reply ..."; dev_file.waitForReadyRead(-1); qDebug() << "reply received!"; quint64 bytes = dev_file.bytesAvailable(); qDebug() << "bytes: " << bytes; line = dev_file_stream.read(bytes); //line = dev_file_stream.readLine(); qDebug() << "line: " << line; }If I use this code, bytesAvailable( ) returns always 0.
If I use readLine( ), reading becomes terribly slow (5 or 6 seconds) probably because the reply doesn't have a '\n' or a '\r'.
If I use readLine(10), reading becomes fast but I'm missing chars because the replies are of different length (20, 30, 40, etc).Any help is appreciated!
Regards,
L. B.p.s. I've been struggling with this problem for years, and have always been forced to write complex signal-slot programs.
@LubomirBogdanov
Firstly, what Qt classes are yourdev_file_streamanddev_file?Your situation may (well) be "messed up" by your use of
dev_file.bytesAvailable();when you have it "wrapped" inside adev_file_stream. Assuming that is some kind of "buffer", it looks like the buffer has filled (fromreadyRead()signal?) with bytes it reads fromdev_file. That would meandev_file.bytesAvailable()now returns0whiledev_file_stream.read()has bytes in it available to read. And usingreadLine()when your device does not send\nis not "useful".Start by just getting rid of your
dev_file_streamwrapper level. Use only thedev_file. Depending on its type, use justread&write, don't worry about<<convenience. That ought work!? Also trydev_file.readAll()without worrying about whatdev_file.bytesAvailable()returns. At least use this to verify what is going on.Of course, nothing will work "quickly" if your device buffers its output, or buffers it for some seconds before flushing.
I will just say that the signals and slots are pretty easy to work with.
waitForReadyRead()is just some Qt code wrapping around the signals with a blocking loop. -
Hi, sorry forgot to include the types:
QFile dev_file; QTextStream dev_file_stream;OK, so I tried as you said, but still the readAll( ) API returns after a few seconds ... Here is the new code:
void osc::run(){ QByteArray line; dev_file.write("*IDN?\n"); line = dev_file.readAll(); qDebug() << "line: " << line; }Regards,
L. B. -
Hi, sorry forgot to include the types:
QFile dev_file; QTextStream dev_file_stream;OK, so I tried as you said, but still the readAll( ) API returns after a few seconds ... Here is the new code:
void osc::run(){ QByteArray line; dev_file.write("*IDN?\n"); line = dev_file.readAll(); qDebug() << "line: " << line; }Regards,
L. B.@LubomirBogdanov
readAll()returns whatever is available at that instant. You can't put it immediately after awrite(), the device will not have had time to respond. Why have you removed yourdev_file.waitForReadyRead(-1)? Or do it better withreadyReadsignal? -
Well, I tried with waitForReadyRead( ) but reading still is slow (5 seconds to get the reply):
void osc::run(){ QByteArray line; dev_file.write("*IDN?\n"); dev_file.waitForReadyRead(-1); line = dev_file.readAll(); qDebug() << "line: " << line; }However, now I read in the Qt documentation:
"Unlike other QIODevice implementations, such as QTcpSocket, QFile does not emit the aboutToClose(), bytesWritten(), or readyRead() signals. This implementation detail means that QFile is not suitable for reading and writing certain types of files, such as device files on Unix platforms"
So, I guess this is not the way to do it ...