Welcome, guest | Sign In | My Account | Store | Cart

Unites N files into a single file (or separates them back).

This utility can be used together w/ my other post titled "Huffman Data Compression" to enable compression of multiple files.

C++, 153 lines
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
//file_uniter.cpp
//Unites N files into a single file (or separates them back).
//FB - 201011301
#include<iostream>
#include<fstream>
#include<string>
#include<vector>
using namespace std;

class str
{
    public:
    string s;
    unsigned int l;
};


int main(int argc, char *argv[])
{
    if(argc > 2)
    {
        cerr<<"Too many arguments!"<<endl;
        exit(1);
    }

    unsigned char uc;
    char c;

    if(argc == 2)
    {
        cout<<"File separator mode!"<<endl;

        ifstream infile(argv[1],ios::in|ios::binary);
        if(!infile)
        {
            cerr<<"The file "<<argv[1]<<" could not be opened!"<<endl;
            exit(1);
        }

        string s;
        unsigned int l,j;
        while(true)
        {
            //get the file name
            getline(infile,s);
            if(s.empty())
                break;
            cout<<"file name:"<<s<<endl;
            //get the file length
            //read 4 bytes and combine them into one 32 bit u. int value
            l=0;
            j=1;
            for(int k=3;k>=0;--k)
            {
                infile.get(c);
                uc=c;
                l+=uc*(j<<(8*k));
            }
            cout<<"size:"<<l<<endl;

            ofstream outfile(s.c_str(),ios::out|ios::binary);
            if(!outfile)
            {
                cerr<<"The file "<<s<<" could not be opened!"<<endl;
                exit(1);
            }

            for(unsigned int i=0;i<l;++i)
            {
                infile.get(c);//cout<<c;
                outfile.put(c);
            }
            //cout<<endl;
            outfile.close();
        }
        infile.close();

    }
    else //argc == 1
    {
        cout<<"File uniter mode!"<<endl;

        cout<<"Input the file names! (just Enter to end)"<<endl;
        vector<str> f_names; //file names
        str st;
        while(true)
        {
            getline(cin,st.s);
            if(st.s.empty())
                break;
            ifstream infile(st.s.c_str(),ios::in|ios::binary);
            if(!infile)
            {
                cerr<<"The file "<<st.s<<" could not be opened!"<<endl;
                exit(1);
            }

            //find out the file length (in bytes)
            st.l=0;
            while(infile.get(c))
            {
                ++st.l;
            }
            //cout<<"size:"<<st.l<<endl;
            infile.clear(); //clear the EOF flag
            infile.seekg(0); //reset get() pointer to beginning
            infile.close();

            f_names.push_back(st);
        }

        cout<<"Input the output file name:"<<endl;
        string s;
        cin>>s;
        ofstream outfile(s.c_str(), ios::out|ios::binary);
        if(!outfile)
        {
            cerr<<"The file "<<s<<" could not be opened!"<<endl;
            exit(1);
        }
        
        //output file format: filename1, filelength1, file1, ...
        for(unsigned int i=0;i<f_names.size();++i)
        {
            outfile.write(f_names.at(i).s.c_str(),f_names.at(i).s.size());
            //add a next line char to the end of the file name
            c='\n';
            uc=c;
            outfile.put(uc);

            //write the file length
            //divide 32 bit u. int values into 4 bytes
            outfile.put(static_cast<unsigned char>(f_names.at(i).l>>24));
            outfile.put(static_cast<unsigned char>((f_names.at(i).l>>16)%256));
            outfile.put(static_cast<unsigned char>((f_names.at(i).l>>8)%256));
            outfile.put(static_cast<unsigned char>(f_names.at(i).l%256));

            //write the file 
            ifstream infile(f_names.at(i).s.c_str(),ios::in|ios::binary);
            for(unsigned int j=0;j<f_names.at(i).l;++j)
            {
                infile.get(c);
                outfile.put(c);
            }
            infile.clear(); //clear the EOF flag
            infile.seekg(0); //reset get() pointer to beginning
            infile.close();
        }            

    }//end else

    return 0;
}

2 comments

FB36 (author) 13 years, 5 months ago  # | flag

Sample run:

C:\Users\FB\Desktop\file_uniter>file_uniter

File uniter mode!

Input the file names! (just Enter to end)

02.jpg

04.jpg

Input the output file name:

images.pac

C:\Users\FB\Desktop\file_uniter>file_uniter images.pac

File separator mode!

file name:02.jpg

size:115237

file name:04.jpg

size:75676

C:\Users\FB\Desktop\file_uniter>

Ivan Mladenov 7 years, 3 months ago  # | flag

How can I change this to read all subdirectories

Created by FB36 on Wed, 1 Dec 2010 (MIT)
C++ recipes (21)
FB36's recipes (148)

Required Modules

  • (none specified)

Other Information and Tasks