Read file in zip without unzip(c++) - c++

I can read file in c++. This is my code:
std::string ReadFile(std::string file)
{
char buff[20480];
std::ifstream fread(file, std::ios::binary | std::ios::app);
fread.read(buff,sizeof(buff));
std::string str = buff;
fread.close();
return str;
}
The variable "file" is the FilePath. And I get a folder .zip, I want to read the file in folder. What should I do? I try to use libzip, but it can't solve my problem, maybe I didn't use it by wrong way.

No. To unzip a file, you must unzip a file.
You don't need to invoke the unzip utility to do it: there are libraries that can expose decompression through a streams API, resulting in code that looks rather similar to what you've written above. But you need to install and learn how to use those libraries.

Unless you have access to the API that allows to unpack your file I don't see how directly in the code.
If you are lazy you could write a small script in whatever language you prefer that does the unpacking and then calls your program on the unpacked file

Assuming, you have unzip available. Did you try something like:
FILE * file = popen("unzip -p filename", "r");
Similarly, popen("gzip -f filename", "r") should work for gzip.
In order to parse the output, I'd refer to this post (with Windows hints). I don't know about a more C++-style way of doing this.

Related

Downloading my programs data from a webserver (Its basically just a .exe turned into .txt) but when I put it into a .exe it does not run?

So currently I am using a basic Http request to pull the exe data from my server weblink.com/Program.exe
it returns my program in .txt form but when I put it into a file it will not run.
I assume this is because I need metadata but have no clue how to find that process or even how to google something as specific as that... So I am either asking for a solution (how to add proper .exe metadata) or if there is a better way to download files like that in C++
*Note I cannot use basic windows functions such as DownloadToFileA or External Library's (Like LibCurl/Curl)
OutFile.open(XorStr("C:\\Users\\Program.exe").c_str(), std::ios::out);
if (OutFile.is_open())
{
OutFile << Output;
//Initialize .exe Meta Data???
}
OutFile.close();
You need to open your file in binary mode otherwise newline translation will screw up your executable:
OutFile.open(XorStr("C:\\Users\\Program.exe").c_str(), std::ios::out | std::ios::binary);

Will File I/O In Current Working Directory Ever Fail?

On my home Linux laptop, I like to write wrapper programs and GUI helpers for things I use frequently. However, I don't like Bash scripting very much, so I do a lot of stuff in C++. However, a lot of times, this requires me to use the system() function from the cstdlib.
This system() command is awesome, but I wanted a way to call system() and receive the stdout/stderror. The system() command only returns the return code from the command. So, in a Bash script, one can do:
myVar=$(ls -a | grep 'search string')
echo $myVar
and myVar will output whatever the stdout was for the command. So I began writing a wrapper class that will add a pipe-to-file to the end of the command, open the file, read all of the piped stdout, and return it as either one long string or as a vector of strings. The intricacies of the class are not really relevant here (I don't think anyway), but the above example would be done like this:
SystemCommand systemCommand;
systemCommand.setCommand("ls -a | grep \'search string\' ");
systemCommand.execute();
std::cout << systemCommand.outputAsString() << std::endl;
Behind the scenes, when systemCommand.execute() is called, the class ensures that the command will properly pipe all stdout/stderr to a randomly generated filename, in the current working directory. So for example, the above command would end up being
"ls -a | grep 'search string' >> 1452-24566.txt 2>&1".
The class then goes attempts to open and read from that file, using ifstream:
std::ifstream readFromFile;
readFromFile.open(_outputFilename);
if (readFromFile.is_open()) {
//Read all contents of file into class member vector
...
readFromFile.close();
//Remove temporary file
...
} else {
//Handle read failure
}
So here is my main question will std::ifstream ever fail to open a recently created file in the current working directory? If so, what would be a way to make it more robust (specifically on Linux)?
A side/secondary question: Is there a very simplified way to achieve what I'm trying to achieve without using file pipes? Perhaps some stuff available in unistd.h? Thanks for your time.
So here is my main question will std::ifstream ever fail to open a recently created file in the current working directory?
Yes.
Mount a USB thumb drive (or some other removable media)
cd to the mount
Execute your program. While it's executing, remove the drive.
Watch the IO error happen.
There's a ton of other reasons too. Filesystem corruption, hitting the file descriptor limit, etc.
If so, what would be a way to make it more robust (specifically on Linux)?
Make temporary files in /tmp, whose entire purpose is for temporary files. Or don't create a file at all, and use pipes for communication instead (Like what popen does, like harmic suggested). Even so, there are no guarantees; try to gracefully handle errors.

How to open a gzip file using fopen (or a function with the same return value as fopen) in C++?

I currently have some code reading files which are not compressed, it uses the following approach to read a file in C++
FILE* id = fopen("myfile.dat", "r");
after obtaining id, different parts of the code access the file using fread, fseek, etc.
I would like to adapt my code so as to open a gzip version of the file, e.g. "myfile.dat.gz" without needing to change too much.
Ideally I would implement a wrapper to fopen, call it fopen2, which can read both myfile.dat and myfile.dat.gz, i.e. it should return a pointer to a FILE object, so that the remaining of the code does not need to be changed.
Any suggestions?
Thank you.
PS: it would be fine to decompress the whole file in memory, if this approach provides a solution
zlib provides analogs of fopen(), fread(), etc. called gzopen(), gzread(), etc. for reading and writing gzip files. If the file is not gzip-compressed, it will be read just as the f functions would. So you would only need to change the function names and link in zlib.

Having stringstream with some data how to gzip it cross platform way?

So we have some stringstream with somedata. With help of which cross platform library we can turn its contents into gziped format (you would save it into file with extention .tar.gz)
Lets get into code: so I have:
stringstream body;
body << std::ifstream( path.string().c_str(), ios::binary).rdbuf();
Which includes shall I add, which function should I call to encode stringstream and which finction to call to turn to put that encoded data into stringstream?
BTW: is there any boost library that can encode into gzip
boost.iostreams has optional built-in support for bzip2 and gzip compression/decompression.
It's not too clear what you're asking. If you mean that the
file (specified by path) is in gzipped format, the easiest
solution is probably to define a pipe input stream, and read it
from gunzip < file through that. If you want to unzip it
within your application, some sort of filtering input streambuf
would seem in order (see boost::iostream).
And I wouldn't use a temporary std::ifstream in any case: you
want to verify that the open succeeded before trying to read.

How to copy files in Visual C++?

I am using Visual C++. How to copy the content of this file to another file?
UINT32 writeToLog(wstring log)
{
wfstream file1 (LOG_FILE_NAME, ios_base::out);
file1 << log;
file1.close();
// want to copy file1 to file2
return 0;
}
What exactly do you want to do? If you need a copy of the data, you can read it in and write it back out again. If you really need a copy of the file, you have to use OS specific calls.
In many cases, reading in the file data and then writing it out again to a different file is a close enough approximation to a copy - like this:
ifstream file1(...);
ofstream file2(...);
std::copy(istream_iterator<char>(file1),istream_iterator<char>(),ostream_iterator<char>(file2));
However that really isn't a copy - it's creating a new file with the same contents. It won't correctly handle hard links or symlinks, it won't correctly handle metadata and it will only 'copy' the default file stream.
If you need a file copy on Windows you should call one of CopyFile, CopyFileEx or CopyFileTransacted depending on your exact requirements.
Standard C++ has no file copying facility, other than reading the file into memory and writing it out again to a different file. As you are using Windows, you can use the CopyFile function - other OSs have similar, OS-specific functions.
The above code from Joe Gauterin did not work for me. I was trying to copy a .tga image file, so maybe something about istream_iterator<char> screwed it up. Instead I used:
ifstream file1(...);
ofstream file2(...);
char ch;
while(file1 && file1.get(ch))
{
file2.put(ch);
}