-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathreadfile_block.cpp
More file actions
197 lines (167 loc) · 5.02 KB
/
readfile_block.cpp
File metadata and controls
197 lines (167 loc) · 5.02 KB
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
// HW # 8 -- complete function CopyFileByBlock below
// Compilation Command: g++ -o block_cp readfile_block.cpp
// Run Command : ./block_cp source-file dest-file block-size
// ./block_cp ./foo.txt ./foo2.txt 4096
// ./block_cp -v ./foo.txt ./foo2.txt 4096
#include <iostream>
#include <fstream>
std::string CopyFileByBlock(const std::string& source_file,
std::string dest_file,
size_t block_size,
bool v)
{
char* buf = nullptr;
std::string retmsg;
std::ifstream sf;
std::ofstream df;
int block_count = 0;
try
{
// allocate a buffer to hold block size bytes
char buffer[block_count];
//1. open the input file stream (sf)
sf.open(source_file, std::ios::in | std::ios::binary);
//2. if the file could not be opened successfully, throw a runtime exception
if(!sf.is_open())
throw std::runtime_error("File: " + source_file + " not found");
//3. open the dest (output) file from writing
df.open(dest_file, std::ios::out | std::ios::binary);
//4. if the file could not be opened successfully, throw a runtime exception
if(!df.is_open())
throw std::runtime_error("File: " + dest_file + " could not be not opened");
//5 read and write the newnew file (block at a time)
sf.read(buffer, block_size);
while (sf.gcount() > 0)
{
if(v)
std::cout << "wrote block" << ":" << ++block_count << " size-> " << sf.gcount() << std::endl;
df.write(buffer,sf.gcount());
/*
attempt to read "block_size" bytes of data from sf into the allocated buffer
while( bytes read greater than zero)
{
if(v)
std::cout << "wrote block" << ":" << ++block_count << " size-> " << sf.gcount() << std::endl;
write the number of bytes read from sf to df
attempt to read "block_size" bytes of data from sf into the allocated buffer
}
*/
df << buffer;
sf.read(buffer, block_size);
}
}
catch(std::exception& ex)
{
retmsg = ex.what();
}
// 6. close source file (sf)
if(sf.is_open())
sf.close();
// 7. close dest file (df)
if(df.is_open())
df.close();
// 8. return buffer memory to the heap (delete)
retmsg = dest_file + " written successfully";
return retmsg;
}
std::string CopyFile(const std::string& source_file,
std::string dest_file,
bool v)
{
char* buf = nullptr;
std::string retmsg;
std::ifstream sf;
std::ofstream df;
int block_count = 0;
try
{
sf.open(source_file, std::ios::in | std::ios::binary);
if(!sf.is_open())
throw std::runtime_error("File: " + source_file + " not found");
// get the length of the input file
sf.seekg (0, sf.end);
int length = sf.tellg();
sf.seekg (0, sf.beg);
// allocate memory using c++ new (not malloc)
char* buf = new char [length];
df.open(dest_file, std::ios::out | std::ios::binary);
if(!df.is_open())
throw std::runtime_error("File: " + dest_file + " could not be not opened");
if(v)
std::cout << "block size: " << length << std::endl;
//read the entire file into the buffer
sf.read(buf, length);
if(sf.gcount() > 0)
{
if(v)
std::cout << "wrote block" << ":" << ++block_count << " size-> " << sf.gcount() << std::endl;
df.write(buf,sf.gcount());
}
}
catch(std::exception& ex)
{
retmsg = ex.what();
}
if(sf.is_open())
sf.close();
if(df.is_open())
df.close();
delete buf; // return memory to the heap
retmsg = dest_file + " written successfully";
return retmsg;
}
void usage()
{
std::cerr << "Usage: cp [-v] source-file dest-file block-size" << std::endl;
}
int main(int argc, char* argv[])
{
std::string source_file;
std::string dest_file;
bool verbose = false;
int block_size;
// handles "cp source-file dest-file"
if(argc == 4)
{
source_file = std::string(argv[1]);
dest_file = std::string( *(argv + 2)); // demonstrate using pointer syntax to index array
block_size = atoi(argv[3]);
if(block_size <= 0)
{
usage();
return 2;
}
}
// handles "cp -v source-file dest-file"
else if(argc == 5)
{
if(std::string(argv[1]) == "-v")
//if(argv[1] == "-v")
{
verbose = true;
source_file = std::string(argv[2]);
dest_file = std::string( *(argv + 3)); // demonstrate using pointer syntax to index array
block_size = atoi(argv[4]);
if(block_size <= 0)
{
usage();
return 2;
}
}
else
{
usage();
return 2;
}
}
else
{
usage();
return 1;
}
//uncomment to test
//std::string msg = CopyFileByBlock(source_file, dest_file, block_size, verbose);
std::string msg = CopyFile(source_file, dest_file, verbose);
std::cout << msg << std::endl;
return 0;
}