Reading Binary Files w/ ifstream - c++

I'm trying to read in an .exe and write it back out. My code works with .txt files but for some reason it is breaking executables. What am I doing wrong?
I'm not sure if I am reading it wrong or writing it wrong..
#include <string>
#include <vector>
#include <iostream>
#include <filesystem>
#include <unordered_set>
#include <Windows.h>
unsigned char *ReadFileAsBytes(std::string filepath, DWORD &buffer_len)
{
std::ifstream ifs(filepath, std::ofstream::binary | std::ifstream::ate);
if (!ifs.is_open())
{
return(nullptr);
}
// Go To End
ifs.seekg(0, ifs.end);
// Get Position (Size)
buffer_len = static_cast<DWORD>(ifs.tellg());
// Go To Beginning
ifs.seekg(0, ifs.beg);
// Allocate New Char Buffer The Size Of File
PBYTE buffer = new BYTE[buffer_len];
ifs.read(reinterpret_cast<char*>(buffer), buffer_len);
ifs.close();
return buffer;
}
void WriteToFile(std::string argLocation, unsigned char *argContents, int argSize)
{
std::ofstream myfile;
myfile.open(argLocation);
myfile.write((const char *)argContents, argSize);
myfile.close();
}
int main()
{
// Config
static std::string szLocation = "C:\\Users\\Admin\\Desktop\\putty.exe";
static std::string szOutLoc = "C:\\Users\\Admin\\Desktop\\putty2.exe";
DWORD dwLen;
unsigned char *szBytesIn = ReadFileAsBytes(szLocation, dwLen);
std::cout << "Read In " << dwLen << " Bytes" << std::endl;
// Write To File
WriteToFile(szOutLoc, szBytesIn, dwLen);
system("pause");
}

You open input file in binary mode, but in this code
std::ofstream myfile;
myfile.open(argLocation);
you open output file without binary mode. And there is no reason to call open separately:
std::ofstream myfile( argLocation, std::ios::out | std::ios::binary | std::ios::trunc);

Related

How to get fstream to save to any windows desktop that opens the .exe in c++

I'm making a program for my brother that will display 50,000 proxie variations and will save them all to a .txt.
How can I make it so any windows machine that uses this code will get the .txt to save to the desktop.
Here's what I have:
fstream file;
file.open("proxies.txt", ios::out);
string line;
streambuf* stream_buffer_cout = cout.rdbuf();
streambuf* stream_buffer_cin = cin.rdbuf();
streambuf* stream_buffer_file = file.rdbuf();
cout.rdbuf(stream_buffer_file);
for (int i = 1; i < 50001; i++)
{
cout << n1 << i << n2 << "\n";
}
file.close();
Thanks for any help.
If I get what you are asking you just need to replace "proxies.txt" with an absolute path to a file in the desktop folder. You can get the desktop directory with the Win32 call SHGetFolderPath and put the path together using the standard (C++17) file system calls if you want, as below:
#include <iostream>
#include <filesystem>
#include <fstream>
#include <shlobj_core.h>
namespace fs = std::filesystem;
std::string desktop_directory() {
char path[MAX_PATH + 1];
if (SHGetFolderPathA(HWND_DESKTOP, CSIDL_DESKTOP, NULL,
SHGFP_TYPE_DEFAULT, path) == S_OK) {
return path;
} else {
return {}; // I'm not sure why this would fail...
}
}
int main() {
std::fstream file;
auto desktop_path = fs::path(desktop_directory()) / "proxies.txt";
file.open(desktop_path, std::ios::out);
// ...
file.close();
return 0;
}

How to manage binary files storage in C++

I need to correctly manage binary files streams for copying and pasting compressed files with .zip extension.
I'm actually trying to make a simple test project: I would like to copy ./src/Directory.zip in ./dest directory initially empty.
The code compiling is correctly done, but at the end of the program the destination directory is still empty and I don't know for which reason.
This is the code:
#include <iostream>
#include <fstream>
#include <vector>
typedef unsigned char BYTE;
std::vector<BYTE> readFile(const char* filename)
{
// open the file:
std::streampos fileSize;
std::ifstream file(filename, std::ios::binary);
// get its size:
file.seekg(0, std::ios::end);
fileSize = file.tellg();
file.seekg(0, std::ios::beg);
// read the data:
std::vector<BYTE> fileData(fileSize);
file.read((char*) &fileData[0], fileSize);
return fileData;
}
int main(){
std::vector<BYTE> fileData = readFile("./src/Directory.zip");
std::ofstream destFile;
destFile = std::ofstream("./dest/Directory.zip", std::ios::out | std::ios::binary);
if ( !destFile )
std::cout << std::strerror(errno) << '\n';
destFile.write( (char*) &fileData[0], sizeof(BYTE)*fileData.size() );
destFile.close();
return 0;
}
I know this could be simply done with std::filesystem::copy_file or other high-level functions, but these binary files will be sent through a socket from a server to a client. Firstly I would like to let this work in a local directory.
I've just followed the advice in the answer and I get this error:
No such file or directory

C++ vector change in text.txt file and add text

#include <iostream>
#include <string>
#include <stdio.h>
#include <cstring>
#include <fstream>
#include <vector>
#include <iterator>
using std::cout;
using std::cin;
using std::endl;
using std::string;
std::string FilesOpen(std::string command)
{
const int size_buffer = 2;
char buffer[size_buffer];
memset(buffer, 0, size_buffer * sizeof(char));
std::string result = "";
// Open pipe to file
FILE* pipe = popen(command.c_str(), "r");
if (!pipe)
{
return "popen failed!";
}
// read till end of process:
while (!feof(pipe))
{
// use buffer to read and add to result
if (fgets(buffer, 2, pipe) != NULL)
{
result += buffer;
memset(buffer, 0, size_buffer * sizeof(char));
}
}
pclose(pipe);
return result;
}
int main(int* agrc, char* agrv[])
{
std::vector<std::string> pole;
std::string text;
// get files names and use to ifstream files
FilesOpen("ls /root/workspace/src/server > /root/workspace/filestext.txt");
// get files info size and names
FilesOpen("ls -l /root/workspace/src/server > /root/workspace/filelist.txt");
// get files name and add vector
std::ifstream files;
files.open("/root/workspace/filestext.txt", std::ios_base::in);
if (!files)
{
std::cout << "Error not open files" << std::endl;
}
while (files >> text)
{
pole.push_back(text);
}
files.close();
for (std::vector<std::string>::iterator it = pole.begin(); it != pole.end(); ++it)
{
std::cout << *it << std::endl;
}
// replace text in shell
std::string filereplace = "/root/workspace/testovaci.sh";
std::ofstream r_file(filereplace.c_str());
char patch[] = "patch=";
if (r_file.is_open())
{
for (int i = 0; patch[i] != '\0'; i++)
r_file.put(patch[i]);
r_file.put('D');
}
r_file.close()
}
I need to get the contents of the file name from the filetext.txt file and ignore the folders and list them in the testovaci.sh script, which looks like this:
neco1
neco2
neco3
patch =
neco4
neco5
I need to put in the testovaci.sh file has been added to patch = "file". "file". "file"
and the folders were ignored, leaving only binary files.
Please help me, as I tried everything but nothing works.

Binary file simple read then write not working

Below is the code. For right now, all I want to do is read in a binary file and then write that same binary to make sure I did the reading and the writing correctly [i.e. without changing the file].
I used test.rar (size 333 bytes -- a rar'ed txt file). The output file was 133kb and fails to extract using winrar (after being renamed test.rar). So I must be doing something wrong and cannot find the mistake.
Also, when I let the commented code run, it outputs "This program cannot run in dos" and starts making beeps and boops repeatedly as it iterates through my vector. It's as if using cout with this data is executing a program. If you know what is causing that, it would be nice to know.
#include "Dip.h"
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
#define USAGE "s\n"
int main(int argc, char **argv)
{
if (argc < 1)
{
cout << USAGE;
return 1;
}
ifstream in(argv[0], ios::binary);
fstream::streampos beg = in.tellg();
in.seekg(0, ios::end);
const fstream::streampos BUFFER_SIZE = in.tellg() - beg;
vector<char> outputBuffer;
if(BUFFER_SIZE)
{
in.seekg(0, ios::beg);
outputBuffer.resize(BUFFER_SIZE);
in.read(&outputBuffer[0], outputBuffer.size());
in.close();
std::ofstream out("output_file", ios::binary);
out.write(&outputBuffer[0], outputBuffer.size());
out.close();
}
else
{
cout << "main::file is empty" << endl;
return 1;
}
//for(vector<char>::const_iterator itr = outputBuffer.begin(); itr !=outputBuffer.end(); ++itr)
//cout << *itr;
// success!
return 0;
}

C++: Getting incorrect file size

I'm using Linux and C++. I have a binary file with a size of 210732 bytes, but the size reported with seekg/tellg is 210728.
I get the following information from ls-la, i.e., 210732 bytes:
-rw-rw-r-- 1 pjs pjs 210732 Feb 17 10:25 output.osr
And with the following code snippet, I get 210728:
std::ifstream handle;
handle.open("output.osr", std::ios::binary | std::ios::in);
handle.seekg(0, std::ios::end);
std::cout << "file size:" << static_cast<unsigned int>(handle.tellg()) << std::endl;
So my code is off by 4 bytes. I have confirmed that the size of the file is correct with a hex editor. So why am I not getting the correct size?
My answer: I think the problem was caused by having multiple open fstreams to the file. At least that seems to have sorted it out for me. Thanks to everyone who helped.
Why are you opening the file and checking the size? The easiest way is to do it something like this:
#include <sys/types.h>
#include <sys/stat.h>
off_t getFilesize(const char *path){
struct stat fStat;
if (!stat(path, &fStat)) return fStat.st_size;
else perror("file Stat failed");
}
Edit: Thanks PSJ for pointing out a minor typo glitch... :)
At least for me with G++ 4.1 and 4.4 on 64-bit CentOS 5, the code below works as expected, i.e. the length the program prints out is the same as that returned by the stat() call.
#include <iostream>
#include <fstream>
using namespace std;
int main () {
int length;
ifstream is;
is.open ("test.txt", ios::binary | std::ios::in);
// get length of file:
is.seekg (0, ios::end);
length = is.tellg();
is.seekg (0, ios::beg);
cout << "Length: " << length << "\nThe following should be zero: "
<< is.tellg() << "\n";
return 0;
}
When on a flavour of Unix, why do we use that, when we have the stat utlilty
long findSize( const char *filename )
{
struct stat statbuf;
if ( stat( filename, &statbuf ) == 0 )
{
return statbuf.st_size;
}
else
{
return 0;
}
}
if not,
long findSize( const char *filename )
{
long l,m;
ifstream file (filename, ios::in|ios::binary );
l = file.tellg();
file.seekg ( 0, ios::end );
m = file.tellg();
file.close();
return ( m – l );
}
Is it possible that ls -la is actually reporting the number of bytes the file takes up on the disk, instead of its actual size? That would explain why it is slightly higher.