My File Splitter function problem

File Splitter function only works with text formats, why?

  • (3 Pages)
  • +
  • 1
  • 2
  • 3

36 Replies - 2711 Views - Last Post: 05 July 2009 - 12:38 PM Rate Topic: -----

#1 Anarion  Icon User is offline

  • The Persian Coder
  • member icon

Reputation: 282
  • View blog
  • Posts: 1,456
  • Joined: 16-May 09

My File Splitter function problem

Post icon  Posted 21 May 2009 - 12:15 PM

This is the function which splits:

void kfs2(string in_name, long int max) {

	stringstream sfename;

	fstream in(in_name.c_str(), ios::binary|ios::in|ios::ate);
	if(in.is_open()) {

		long int fsize = in.tellg();
		in.seekg(0, ios::beg);

		long int r = fsize;
		int i = 0;
		char * buffer = new char[max+1];
		fstream out;
		int len = in_name.length();
		while(max <= r) {
			i++;
			sfename<<in_name.substr(0, len-4)<<".part"<<i;
			in.read(buffer, max);
			out.open(sfename.str().c_str(), ios::out|ios::binary);
			out.write(reinterpret_cast<const char *>(buffer), max);
			out.close();
			sfename.str("");
			r -= max;
		}
		if(r>0) {
			i++;
			sfename<<in_name.substr(0, len-4)<<".part"<<i;
			in.read(buffer, r);
			out.open(sfename.str().c_str(), ios::out|ios::binary);
			out.write(reinterpret_cast<const char *>(buffer), r);
			out.close();
			sfename.str("");
		}
		
		in.close();
		out.close();
		delete[] buffer;
	}
}


Thanks.

Is This A Good Question/Topic? 0
  • +

Replies To: My File Splitter function problem

#2 UG Cyber  Icon User is offline

  • D.I.C Addict

Reputation: 32
  • View blog
  • Posts: 545
  • Joined: 24-July 08

Re: My File Splitter function problem

Posted 21 May 2009 - 12:29 PM

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

#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
}



That should give you atlease a basic idea.
Was This Post Helpful? 0
  • +
  • -

#3 Anarion  Icon User is offline

  • The Persian Coder
  • member icon

Reputation: 282
  • View blog
  • Posts: 1,456
  • Joined: 16-May 09

Re: My File Splitter function problem

Posted 21 May 2009 - 12:54 PM

Oops, sorry it seems that i must visit a doctor! :blink: my code worked fine and runs smoothly...
Was This Post Helpful? 0
  • +
  • -

#4 r.stiltskin  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1833
  • View blog
  • Posts: 4,927
  • Joined: 27-December 05

Re: My File Splitter function problem

Posted 21 May 2009 - 01:17 PM

View PostAnarion, on 21 May, 2009 - 02:54 PM, said:

Oops, sorry it seems that i must visit a doctor! :blink: my code worked fine and runs smoothly...

Thanks for posting that. I've been studying it for a while & couldn't find anything wrong. :crazy:
Was This Post Helpful? 0
  • +
  • -

#5 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2246
  • View blog
  • Posts: 9,236
  • Joined: 18-February 07

Re: My File Splitter function problem

Posted 21 May 2009 - 08:25 PM

What happens when when you run the code.

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.
Was This Post Helpful? 0
  • +
  • -

#6 Anarion  Icon User is offline

  • The Persian Coder
  • member icon

Reputation: 282
  • View blog
  • Posts: 1,456
  • Joined: 16-May 09

Re: My File Splitter function problem

Posted 23 May 2009 - 12:22 AM

Sorry i disturbed you :) but at least it works cool.

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.
Was This Post Helpful? 0
  • +
  • -

#7 janotte  Icon User is offline

  • code > sword
  • member icon

Reputation: 988
  • View blog
  • Posts: 5,135
  • Joined: 28-September 06

Re: My File Splitter function problem

Posted 23 May 2009 - 12:39 AM

View PostAnarion, on 22 May, 2009 - 11:22 PM, said:

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.


I'm really not at all clear on what you mean by the above.

Could you spell it out in greater detail?

This post has been edited by janotte: 23 May 2009 - 12:39 AM

Was This Post Helpful? 0
  • +
  • -

#8 r.stiltskin  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1833
  • View blog
  • Posts: 4,927
  • Joined: 27-December 05

Re: My File Splitter function problem

Posted 23 May 2009 - 07:35 AM

View PostAnarion, on 23 May, 2009 - 02:22 AM, said:

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 - 07:44 AM

Was This Post Helpful? 1
  • +
  • -

#9 Anarion  Icon User is offline

  • The Persian Coder
  • member icon

Reputation: 282
  • View blog
  • Posts: 1,456
  • Joined: 16-May 09

Re: My File Splitter function problem

Posted 03 June 2009 - 09:10 AM

Quote

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. :rolleyes:
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. :rolleyes:
Was This Post Helpful? 0
  • +
  • -

#10 Anarion  Icon User is offline

  • The Persian Coder
  • member icon

Reputation: 282
  • View blog
  • Posts: 1,456
  • Joined: 16-May 09

Re: My File Splitter function problem

Posted 15 June 2009 - 11:14 AM

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.
void kfs(string in_name, long int max) {
	stringstream sfename;
	fstream in(in_name.c_str(), ios::binary|ios::in|ios::ate);
	if(in.is_open()) {
		long int fsize = in.tellg();
		in.seekg(0, ios::beg);
		long int r = fsize, p;
		int i = 0;
		char * buffer = new char[BUFFER_SIZE+1];
		fstream out;
		fstream inst("toc.tmp", ios::out);
		if(inst.is_open()) {
			inst<<in_name<<";";
			int len = in_name.length();
			while(max <= r) {
				i++;
				sfename<<in_name.substr(0, len-4)<<".part"<<i;
				out.open(sfename.str().c_str(), ios::out|ios::binary);
				p = max;
				if(out.is_open()) {
					while(p>=BUFFER_SIZE) {
						in.read(buffer, BUFFER_SIZE);
						out.write(buffer, BUFFER_SIZE);
						p -= BUFFER_SIZE;
					}
					if(p>0) {
						in.read(buffer, p);
						out.write(buffer, p);
					}
				}
				out.close();
				inst<<sfename.str().c_str()<<";";
				sfename.str("");
				r -= max;
			}
			if(r>0) {
				i++;
				sfename<<in_name.substr(0, len-4)<<".part"<<i;
				out.open(sfename.str().c_str(), ios::out|ios::binary);
				if(out.is_open()) {
					p=r;
					while(p>=BUFFER_SIZE) {
						in.read(buffer, BUFFER_SIZE);
						out.write(buffer, BUFFER_SIZE);
						p -= BUFFER_SIZE;
					}
					if(p>0) {
						in.read(buffer, p);
						out.write(buffer, p);
					}
				}
				out.close();
				inst<<sfename.str().c_str();
				sfename.str("");
			}
			in.close();
			inst.close();
		}
		delete[] buffer;
		ifstream toc_in("toc.tmp", ios::binary|ios::ate);
		ifstream merger_in("merger_data.exe", ios::binary|ios::ate);
		string m_name = "merge_" + in_name + ".exe";
		ofstream merger_out(m_name.c_str(), ios::binary);
		if(toc_in.is_open() && merger_in.is_open() && merger_out.is_open()) {
			int toc_len = toc_in.tellg();
			int merger_len = merger_in.tellg();
			char * toc_data = new char[toc_len+1];
			char * merger_data = new char[merger_len+1];
			if(toc_data && merger_data) {
				merger_in.read(merger_data, merger_len);
				merger_out.write(merger_data, merger_len);
				toc_in.read(toc_data, toc_len);
				merger_out.write(toc_data, toc_len);
			} else {
				cout<<"Error Allocating Memory!"<<endl;
			}
			delete[] toc_data; delete[] merger_data;
		} else {
			cout<<"Cannot read file!"<<endl;
		}
		toc_in.close();
		merger_in.close();
		merger_out.close();
		system("del toc.tmp");
	}
}

Whta do i have to do ? im totally lost in this.
Was This Post Helpful? 0
  • +
  • -

#11 jjl  Icon User is online

  • Engineer
  • member icon

Reputation: 1046
  • View blog
  • Posts: 4,449
  • Joined: 09-June 09

Re: My File Splitter function problem

Posted 15 June 2009 - 04:36 PM

are you just trying to merge two files?
you can just use the
 rdbuf() 
function
Was This Post Helpful? 0
  • +
  • -

#12 r.stiltskin  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1833
  • View blog
  • Posts: 4,927
  • Joined: 27-December 05

Re: My File Splitter function problem

Posted 15 June 2009 - 06:19 PM

View PostAnarion, on 15 Jun, 2009 - 01:14 PM, said:

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.
Was This Post Helpful? 0
  • +
  • -

#13 Anarion  Icon User is offline

  • The Persian Coder
  • member icon

Reputation: 282
  • View blog
  • Posts: 1,456
  • Joined: 16-May 09

Re: My File Splitter function problem

Posted 16 June 2009 - 04:29 AM

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 ?
Was This Post Helpful? 0
  • +
  • -

#14 r.stiltskin  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1833
  • View blog
  • Posts: 4,927
  • Joined: 27-December 05

Re: My File Splitter function problem

Posted 16 June 2009 - 04:30 PM

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
Was This Post Helpful? 0
  • +
  • -

#15 Anarion  Icon User is offline

  • The Persian Coder
  • member icon

Reputation: 282
  • View blog
  • Posts: 1,456
  • Joined: 16-May 09

Re: My File Splitter function problem

Posted 18 June 2009 - 03:45 AM

:) 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 :blink:
Code for Merger Application which must read data from it's end:
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

void kfm(string, int);
string getToc(char * file);

int main(int argc, char * argv[]) {
	string toc = getToc(argv[0]);
	kfm(toc, 10);
	system("pause");
	return 0;
}

string getToc(char * file) {
	char * toc;
	string stoc;
	ifstream self(file, ios::binary|ios::ate);
	if(self.is_open()) {
		long int end = self.tellg();
		long int i = end;
		char c = ' ';
		cout<<"Reading TOC..."<<endl;
		while(c != '|' && i>=0) {
			i -= 1;
			self.seekg(i);
			self.read(&c, 1);
		}
		int len = end-i;
		cout<<"TOC Length: "<<len<<" bytes"<<endl;
		toc = new char[len+1];
		if(toc) {
			self.read(toc, len);
			stoc.assign(toc);
			delete[] toc;
		} else {
			cout<<"Allocation error"<<endl;
		}
		
	} else {
		cout<<"Cannot open self!"<<endl;
	}
	self.close();
	return stoc;
}

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:
#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;
}

void kfs(string in_name, long int max) {
	stringstream sfename;
	fstream in(in_name.c_str(), ios::binary|ios::in|ios::ate);
	if(in.is_open()) {
		long int fsize = in.tellg();
		in.seekg(0, ios::beg);
		long int r = fsize, p;
		int i = 0;
		char * buffer = new char[BUFFER_SIZE+1];
		fstream out;
		fstream inst("toc.tmp", ios::out);
		if(inst.is_open()) {
			inst<<"|"<<in_name<<";";
			int len = in_name.length();
			while(max <= r) {
				i++;
				sfename<<in_name.substr(0, len-4)<<".part"<<i;
				out.open(sfename.str().c_str(), ios::out|ios::binary);
				p = max;
				if(out.is_open()) {
					while(p>=BUFFER_SIZE) {
						in.read(buffer, BUFFER_SIZE);
						out.write(buffer, BUFFER_SIZE);
						p -= BUFFER_SIZE;
					}
					if(p>0) {
						in.read(buffer, p);
						out.write(buffer, p);
					}
				}
				out.close();
				inst<<sfename.str().c_str()<<";";
				sfename.str("");
				r -= max;
			}
			if(r>0) {
				i++;
				sfename<<in_name.substr(0, len-4)<<".part"<<i;
				out.open(sfename.str().c_str(), ios::out|ios::binary);
				if(out.is_open()) {
					p=r;
					while(p>=BUFFER_SIZE) {
						in.read(buffer, BUFFER_SIZE);
						out.write(buffer, BUFFER_SIZE);
						p -= BUFFER_SIZE;
					}
					if(p>0) {
						in.read(buffer, p);
						out.write(buffer, p);
					}
				}
				out.close();
				inst<<sfename.str().c_str()<<';';
				sfename.str("");
			}
			in.close();
			inst.close();
		}
		delete[] buffer;
		ifstream toc_in("toc.tmp", ios::binary|ios::ate);
		ifstream merger_in("merger_data.exe", ios::binary|ios::ate);
		string m_name = "merge_" + in_name + ".exe";
		ofstream merger_out(m_name.c_str(), ios::binary);
		if(toc_in.is_open() && merger_in.is_open() && merger_out.is_open()) {
			int toc_len = toc_in.tellg();
			toc_in.seekg(0, ios::beg);
			int merger_len = merger_in.tellg();
			merger_in.seekg(0, ios::beg);
			char * toc_data = new char[toc_len+1];
			char * merger_data = new char[merger_len+1];
			if(toc_data && merger_data) {
				merger_in.read(merger_data, merger_len);
				merger_out.write(merger_data, merger_len);
				merger_out.close();
				toc_in.read(toc_data, toc_len);
				ofstream m_out(m_name.c_str(), ios::binary|ios::ate|ios::app);
				if(m_out.is_open()) {
					m_out.write(toc_data, toc_len);
					m_out.close();
				} else {
					cout<<"Cannot Open file "<<m_name.c_str()<<endl;
				}
			} else {
				cout<<"Error Allocating Memory!"<<endl;
			}
			delete[] toc_data; delete[] merger_data;
		} else {
			cout<<"Cannot read file!"<<endl;
		}
		toc_in.close();
		merger_in.close();
		merger_out.close();
		system("del toc.tmp");
	}
}

Was This Post Helpful? 0
  • +
  • -

  • (3 Pages)
  • +
  • 1
  • 2
  • 3