I have a QFile that needs to be sent through a LAN network. In order to do so, I convert the QFile into QByteArray by doing:
//! [Inside a QTcpSocket class]
// Get the file name using a QFileDialog
QFile file(QFileDialog::getOpenFileName(NULL, tr("Upload a file")));
// If the selected file is valid, continue with the upload
if (!file.fileName().isEmpty) {
// Read the file and transform the output to a QByteArray
QByteArray ba = file.readAll();
// Send the QByteArray
write(ba);
}
When I receive it, I can transform it easily by using:
void saveFile(QByteArray ba) {
// Ask the user where he/she wants to save the file
QFile file(QFileDialog::getSaveFileName(NULL, tr("Save file")));
// Check that the path is valid
if (!file.fileName().isEmpty()) {
// Write contents of ba in file
file.write(ba);
// Close the file
file.close();
}
}
However, I would like to know the file name (such as Document.docx) or at least know its extension to avoid forcing the user to know exactly which file type he has received.
Ideally, when the file is uploaded, the receiver user will be prompted to save the file. For example:
Sender sends Document1.docx
Receiver gets prompted if he/she wants to save Document1.docx
Based on receiver's decision, Document1.docx is saved in receiver's workstation.
So, my question is: Is there any way to know the name and extension of a QFile when its transformed into a QByteArray and then transformed again (in another computer) into a QFile?
You just read the raw bytes of a file using QFile::readAll().
Q: Is there any way to know the name and extension of a QFile when its
transformed into a QByteArray?
No. The file name and extension is not necessarily inserted in bytes of a file. It depends on the file format. For example you can make your custom file with a specific extension and put its name and extension at the begging of the bytes.
You can send the name and extension of the file manually before sending the raw bytes of the file. Before that you can send the length of name and extension and the number of bytes in file. This way you know how many bytes are related to name, extension and raw bytes.
The answer on you particular question is NO. Although particular files contain the so called magic numbers (or signatures) in the beginning of the data, this signature should be unique for particular file format.
But the problem you have described seems not be serious, because you can simply send filename string and extension string separately of the file content.
Related
I am making a console text editor that continuously saves its content to a text file as text is being written to the editor.
FileEditor editor("C://temp/test.txt");
while (true) {
if (_kbhit()) {
editor.keypress(_getche());
system("cls");
std::cout << editor.content();
editor.save();
}
}
In order to directly save the written content to the text file without having to close() and reopen() the file everytime, I flush the ofstream file buffer directly after inserting text into it.
class FileEditor {
private:
std::ofstream _file;
std::string _content;
public:
// ...
void save() {
_file << _content << std::flush;
}
// ...
};
The problem is when I write multiple characters into the console, for example the string abcd, it will write a to the file, then aab, adding ab to the current buffer content, then aababc, and so on.
Therefore, I wish to clear the ofstream file buffer to replace its contents instead of continuously adding new text to the buffer. Is there a method for clearing the file buffer? Is there a better way of doing what I'm trying to achieve?
I tried finding a method for clearing the buffer and I tried searching online for anyone who might've had the same problem as me, but to no avail.
The problem is when I write multiple characters into the console, for example the string abcd, it will write a to the file, then aab, adding ab to the current buffer content, then aababc, and so on.
Your problem has nothing to do with the file buffer. You are not clearing the editor buffer after writing it to the file, so you are writing the same characters to the file over and over.
The user types a, so your editor buffer is a, and you write a to the file.
Then, the user types b, so your editor buffer is now ab, and you write ab to the file.
Then, the user types c, so your editor buffer is now abc, and you write abc to the file.
Then, the user types d, so your editor buffer is now abcd, and you write abcd to the file.
And so on.
You need to write only the new characters that have entered the editor buffer since the last write to the file. For instance, maintain an index into the editor buffer where the last file write left off, and then have the next file write pick up from that index and advance it for the next file write, etc.
Therefore, I wish to clear the ofstream file buffer to replace its contents instead of continuously adding new text to the buffer. Is there a method for clearing the file buffer? Is there a better way of doing what I'm trying to achieve?
The only way to do this with ofstream is to close the re-open the file stream so that the current file content can be truncated. Otherwise, you will have to resort to using platform-specific APIs to truncate the file without closing it first.
Hi im new to Qt and im trying to read for example the first 4 bytes of my .txt file and show it. I've been searching and figure that QbyteArray may help me best in this situation. so I really like to know how can i read the first 4 bytes of my file with QbyteArray? (appreciate if u write any example code)
Assuming your code contains something like this:
QFile file{ "path/to/file.txt" };
You can read a number of bytes from a file with file.read(n), assuming n to be a number of bytes. you can also use file.readAll() to get the entire thing
for more advanced input/output operations, you can use the QTextStream class as such:
QFile file { "path/to/file.txt" };
QTextStream stream { &file };
(This is a stream that can read and write data to the provided device, here, a file.)
For more info, see here:
https://doc.qt.io/qt-6/qfile.html for QFile
https://doc.qt.io/qt-6/qtextstream.html for QTextStream
My supervisor developed a simulator (Its a collection of codes) that reads data from a file and converts them to a signal (for example optical signal, etc.), and then the simulator saves this signal to a .sgn file.
He asked me to read a .jpg image in VS 2019 and convert it to a signal of type byte and then save the signal to .sgn file. However, when I save the signal and change its extension to .jpg (in order to make sure that the signal contains the image data) it cannot be open.
I compared the information of the original image and my signal and I see some extra garbage in the signal as shown in pictures.
Original image
Resulted image(Signal image)
My questions are (thank you so much in advance):
In order to solve this issue, should I read the image header file separately?
Am I reading the image file correctly? (the simulator is huge, so I can not put all the codes)
Do you have any other idea about where the problem is? like the buffer or something else.
std::ifstream inFile;
inFile.open("1.jpg");
std::byte out; // type of output signal
int length = sizeof(std::byte);
char * memblock = new char[length];
for (int i = 0; i < process; i++) { //this line is related to the circular buffer
inFile.read(memblock, length);
std::byte * byte_values = (std::byte*)memblock;
out = *byte_values;
outputSignals[0]->bufferPut(out); // related to saving the output signal
}
delete[] memblock;
jpeg and similar files contain binary data, hence you should open the file in binary mode for the data to be read correctly.
Simple Example
I need to write a program that allows me to read the names of every file in a directory, and also the type of a file. While I can get the filenames, I am unable to get how I am supposed to find the type. The only thing I can think of is to use its metadata, but I'm not even sure how to begin with that.
I'm trying for an OS independent solution, but I'll be happy if it works only on Windows or Linux only as well.
Note: Please do NOT give solutions that involve searching for a dot, and anything in between. These days, almost no file had a .pdf or something attached to it. When you read the filename, all you get is sample, and not sample.txt.
Also, if it is not compatible with Qt, I'd appreciate if you could mention this in your answer so I can look take appropriate actions (I'm working on Qt because of GUI).
File Extension
As #CMLDMR pointed out, QFileInfo::suffix() and QFileInfo::completeSuffix() methods will return the file extension. However, file extension may be omitted, invalid, unknown, etc.
So, according to your actual question, you want to know the file format, not its extension as stated in the first revision.
File Format
Qt 5 has a class QMimeDatabase. It allows you to discover the file MIME type by its contents. Let's say we have an mpeg music file with no extension:
QMimeDatabase db;
QMimeType mime = db.mimeTypeForFile("C:/music", QMimeDatabase::MatchContent);
qDebug() << mime.name(); // Name of the MIME type ("audio/mpeg").
qDebug() << mime.suffixes(); // Known suffixes for this MIME type ("mp3", "mpga").
qDebug() << mime.preferredSuffix(); // Preferred suffix for this MIME type ("mp3").
File Extension + File Format
If you still want to give priority to the file extension and parse the file contents only if the suffix is not present, omit the QMimeDatabase::MatchContent argument – the default QMimeDatabase::MatchDefault will be used. See QMimeDatabase::MatchMode for more informtaion.
Note that Qt uses different MIME databases for different operating systems, so the results may vary.
QFileInfo fi("/tmp/archive.tar.gz");
QString ext = fi.suffix(); // ext = "gz"
suffix function is give you a file extension.
OR
QFileInfo fi("/tmp/archive.tar.gz");
QString ext = fi.completeSuffix(); // ext = "tar.gz"
you can use each of other which one is correct for you.
This code independent but Qt.
For Details LINK
I have a program that load data from a file using std::ifstream and store the data in a structure. After that, I verify if the data I want was in the file. If it is not, I ask the user to modify the file and press a key. I then reload the file. The problem is that even if the user modified the file, I always get the same data in the file because the file seems to be cache in the application. I've seen that in win32 API, it's possible to use the flag FILE_FLAG_NO_BUFFERING to avoid using a buffered copy when reading a file, but I would like to use that feature with std::ifstream. Is there any way to use the handle created through win32 api with ifstream or anyway to force it directly in std::ifstream ?
Here's a "simplified" code sample:
SomeStructure s = LoadData(fileName);
while(!DataValid(s))
s = LoadData(fileName);
SomeStructure LoadData(const std::string& fileName)
{
std::ifstream fileStream;
while(!OpenFileRead(fileName, fileStream))
{
std::cout<<"File not found, please update it";
fileStream.close();
//Wait for use input
std::string dummy;
std::getline(std::cin, dummy);
}
//... Read file, fill structure, and return
std::string line;
while(std::getline(fileStream, line) && line!="")
{
//At this point, I can see that line is wrong
StringArray namedatearray=Utils::String::Split(line, "|");
assert(namedatearray.size()==2);
//Add data to my structure ( a map)
}
fileStream.close();
//return structure
}
bool OpenFileRead(const std::string& name, std::fstream& file)
{
file.open(name.c_str(), std::ios::in);
return !file.fail();
}
Thanks.
Edit: Of course, it was a mistake because I had two time the same file in two very similar path. Looking at the handle of the file open with process explorer (and not the relative file path made me found it).
Instead of thinking that this is due to some kind of "buffering", I would look for the obvious things first.
Are you sure the user is changing the same file that you're reading?
Are you certain reloading the data is properly updating your data structure in memory?
Are you confident that DataValid() is doing what you want?
The fact that the OS uses file buffers to increase disk performance is generally not visible from the application level. As long as you're looking at the same file, the OS knows that the user updated the file, and if you reopen it, then you'll see the changed data. If the data never even had a chance to get flushed to disk, that won't affect your application.