Join 300,303 C++ Programmers for FREE! Get instant access to thousands of C++ experts, tutorials, code snippets, and more! There are 2,107 people online right now. Registration is fast and FREE... Join Now!
To be honest with you, i can't believe it works with the text file....here is a simpler way. It's written in browser but it will atleast give you an idea
cpp
#include <fstream> using namespace std;
bool split(char * file, char * output1, char *output2) { ifstream fin; ofstream fout; ofstream fout2; int inputsize; int half; fin.open(file, ios::binary); if (!fin) { return false; } fout.open(output1, ios::binary); if (!fout) { return false; } fout2.open(output2, ios::binary); if (!fout2) { return false; } fin.seekg(0, ios::end); //go to the end of the input inputsize = fin.tellg(); //get current location in bytes half = inputsize / 2; char Buffer[inputsize]; //Create a buffer for the file to load into fin.seekg(0, ios::beg); //go to beginning of file fin.read(Buffer, inputsize); //This will load entire file into a buffer fin.close(); //your done with that file!
for (int i = 0; i <= half; i++) { fout << Buffer[i]; } fout.close(); //That would be the first half of the file for (int i = half; i <= inputsize; i++) { fout2 << Buffer[i]; } fout2.close(); // that would be the 2nd half of the file. return true; //your done }
I don't have a reference with this, but I think when using fstream you have to open with ios::in and ios::out enabled. I seem to remember there is some trouble getting the file open otherwise... I just can't find a reference on it.
I used "ifstream" and "ofstream", they don't need the part "ios::in" or etc.
now i have to write the merge function to make t perfect, any ideas ? my idea is to generate an exe file that has the part-names inside it and when user executes it, the original file is made.
my idea is to generate an exe file that has the part-names inside it and when user executes it, the original file is made.
That sounds unnecessarily difficult and unnecessarily restrictive -- it will only be usable on Windows systems. Why not simply generate a text file with a sequential list of the parts, and a function that reads that text file, opens the corresponding files and merges them in order.
Edit: looked again at your splitting function. You could enhance your output-file naming with a counter. i.e., the file extensions could be .part0, .part1, ... Then the merging function only needs to know the filename stem and the number of parts.
This post has been edited by r.stiltskin: 23 May, 2009 - 06:44 AM
I'm really not at all clear on what you mean by the above. Could you spell it out in greater detail?
I meant something like the way self-extractors work, but as "r.stiltskin" said, creating a text file with the names is way better, sorry with my bad idea, i just wanted to make it with less number of files. thanks for telling me about it
QUOTE
Edit: looked again at your splitting function. You could enhance your output-file naming with a counter. i.e., the file extensions could be .part0, .part1, ... Then the merging function only needs to know the filename stem and the number of parts.
the code already creates them using the format you mentioned.
I came into this problem: i re-wrote some parts of the code to make an exe file with instructions to merge the file, i wrote and compiled the code for merger app which reads data from the end of itself, and it works properly. but when i run the merger exe which is newly created with data at the end of it, and when i run it, it gives me errors that it cant be run.
I came into this problem: i re-wrote some parts of the code to make an exe file with instructions to merge the file, i wrote and compiled the code for merger app which reads data from the end of itself, and it works properly. but when i run the merger exe which is newly created with data at the end of it, and when i run it, it gives me errors that it cant be run. ... Whta do i have to do ? im totally lost in this.
First, please rewrite the above because I don't understand what you are trying to say, and as nobody else has offered an answer I'm guessing that I'm not the only one.
It might be helpful to post the error messages as well.
OK, the function "kfs" must do these things: it will split the file into parts with the given size whch it does correct now. other thing it must do is to copy the merger program's exe file and add a TOC at the end of it. this TOC data will have the original file's name which we split and also it contains the part names (like fname;fname.part1;fname.part2;). But after this function does it's job, when i run the newly created exe, it comes up with error. do i need to do anything special or is my code wrong ?
A Windows .exe file is a compiled, executable program. Your merge_[in_name].exe is (I guess) a string made up of multiple filenames, or something like that. (Sorry, I don't have the time or patience now to study it in detail.) But what I'm sure of is that it's not a program and that's why the OS is telling you it's not runnable.
Calling it "ios::binary" and naming it ".exe" doesn't make it a program. It's still just a text file in disguise. You know what a program is -- since you're writing one, right?
As I told you a few weeks ago, you can easily write a program that takes a list of files as its input, and merges those files. Then your splitter program just has to write a file containing the list of names of the split files it produced, and the merger program can use that file of names to re-merge them.
If you insist on having an executable that has the partial-file list built-in, then you can write a splitter program that does all of these things: 1a. writes a text file containing the complete source-code for the merger program, including the list of partial-file names (as, say, an array of strings) 2. closes that output file 3. compiles the merger source code, presumably using a system call to run the compiler
Thanks for spending time for replying, I already made an individual program that reads from the end of itself like this:
[binary data of exe file which reads from itself][custom data]
this was how it must work... i tweaked the code a bit and now it runs ok and can read the first part of the custom data which is the original file's name. But when it must read the file-parts' names, it reads empty. so my program wants to read from the file "" and that's very wrong. i don't know what i did wrong Code for Merger Application which must read data from it's end:
void kfm(string toc, int buffer_size) { int ii = toc.find_first_of(';', 0); int i=0; string fname = toc.substr(i, ii-i); ofstream out(fname.c_str(), ios::binary); if(out.is_open()) { string pn; ifstream pin; char * data_block = new char[buffer_size+1]; data_block[buffer_size] = '\0'; if(data_block) { long int psize, r; while(ii<toc.length()) { i = ii; ii = toc.find_first_of(';', i); pn = toc.substr(i, ii-i); pin.open(pn.c_str(), ios::binary|ios::ate); if(pin.is_open()) { psize = pin.tellg(); pin.seekg(0, ios::beg); // USE BUFFERED METHOD if(psize > buffer_size) { r = psize; while(r>=buffer_size) { pin.read(data_block, buffer_size); data_block[buffer_size] = '\0'; out.write(data_block, buffer_size); r -= buffer_size; } if(r>0) { pin.read(data_block, r); data_block[r] = '\0'; out.write(data_block, r); } // USE NORMAL METHOD } else { pin.read(data_block, psize); out.write(data_block, psize); } pin.close(); } else { cout<<"Cannot read from the file \""<<pn<<"\""<<endl; break; } } delete[] data_block; } else { cout<<"Cannot Allocate Memory"<<endl; } } else { out.close(); cout<<"Cannot create the file \""<<fname<<"\""<<endl; } }
This is the program which splits the file and creates the merger_[in_name].exe:
CODE
#include <iostream> #include <fstream> #include <string> #include <sstream> using namespace std; const int MB = 1048576; const int KB = 1024; const int GB = 1073741824; const int BUFFER_SIZE = 10;
void kfs(string in_name, long int max); long int calc_size(char * in);
int main() { /* GET INPUT FILE NAME */ string fname; cout<<"Enter file's name: "; getline(cin, fname); /* GET MAXIMUM SIZE OF PARTS */ char * maxc = new char[12]; maxc[11] = '\0'; cout<<"Enter maximum size allowed: "; cin.getline(maxc, 11); long int max = calc_size(maxc); delete[] maxc; /* SPLIT THE FILE */ kfs(fname, max); system("pause"); return 0; }
long int calc_size(char * in) { int i; long int s; char c; for(i=0; i<=10; i++) { c = in[i]; if(c=='k' || c=='K' || c=='m' || c=='M' || c=='g' || c=='G') { break; } } string in2 = in; in2.substr(0, i-1); s = strtol(in2.c_str(), NULL, 10); if(c=='k' || c=='K') { s *= KB; } else if(c=='m' || c=='M') { s *= MB; } else if(c=='g' || c=='G') { s *= GB; } return s; }
Well, actually the base idea was not mine, I read it on the internet that people do that for self-extracting exe files. Then I thought I can use this for my application to make it easier to use it.
I am 90% sure that the filesplitter program writes them correctly because I can read the original file's name from the exe file. I am checking it over again...
hahaha good point! THANKS actually i found this some hours ago myself but there is another problem when i write ii+1. there will be an extra loop which wants to read another file and outputs it cannot read the file "" but actually the program does it's job correct at least. what do i have to do in order to fix that ?
I have even rewrote that part like this:
CODE
while(ii<toc.find_last_of(';', 0)) { i = ii+1;
still i got that output but the program merges files correct