-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathProgram.cs
143 lines (120 loc) · 5.13 KB
/
Program.cs
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
using Microsoft.Extensions.Logging;
using System;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Mime;
using System.Threading.Tasks;
namespace FileDownloader
{
class Program
{
static async Task Main(string[] args)
{
await FFDLMAIN();
}
//Main Method where information is being retreived
static async Task FFDLMAIN()
{
//Provides Link Information
Console.WriteLine("Paste the Download Link here");
Console.Write(">");
string Link = Console.ReadLine() ?? "";
Console.Clear();
//Provides fileName Information
Console.WriteLine("What would you like to name the file?");
Console.Write(">");
string fileName = Console.ReadLine() ?? "";
Console.Clear();
//Retreives the file type and splits it after the / upon retreival
string filetype = Link_Request.File_Type(Link);
string[] parts = filetype.Split("/");
string Fcontenttype = ("." + parts[1]);
//Prompts user with the file information obtained for validation
Console.WriteLine("Is this the correct file type? || " + fileName + Fcontenttype + "\n Press 1 for YES\n Press 2 for NO");
//Checks for Key input when 1 is pressed it sends the information to be finalized and downloaded
//Checks for Key input when 2 in pressed it sends it to SelfType where the user will input the correct file type
ConsoleKey key;
do
{
key = Console.ReadKey(true).Key;
switch (key)
{
case ConsoleKey.D1:
Console.Clear();
SelfFinalize(fileName, Fcontenttype, Link);
break;
case ConsoleKey.NumPad1:
Console.Clear();
SelfFinalize(fileName, Fcontenttype, Link);
break;
case ConsoleKey.D2:
Console.Clear();
SelfType(fileName, Link);
break;
case ConsoleKey.NumPad2:
Console.Clear();
SelfType(fileName, Link);
break;
}
}
//While 1 or 2 are not being pressed nothing will happen
while (key != ConsoleKey.D1 && key != ConsoleKey.NumPad1 && key != ConsoleKey.NumPad2 && key != ConsoleKey.D2);
}
//Method used for correcting file information if file type retreived via link is incorrect
private static void SelfType(string fileName, string Link)
{
//prompts user to input the correct file type
Console.WriteLine("Input the correct file type");
Console.Write(">");
string NewPreType = Console.ReadLine();
//adds a '.' before the file type before passing it on to finalize
string Fcontenttype = "." + NewPreType;
Console.Clear();
SelfFinalize(fileName, Fcontenttype, Link);
}
//Taks information provided and chunks the file into quarters and downloads them at the same time
static void SelfFinalize(string fileName, string Fcontenttype, string Link)
{
long size = Link_Request.File_Size(Link);
DownloadChunk[] chunks = GetChunks(4 , size);
Parallel.ForEach(chunks, (chunk) =>
{
HttpWebRequest request = WebRequest.CreateHttp(Link);
request.AddRange(chunk.Start, chunk.End);
using WebResponse response = request.GetResponse();
using Stream responseStream = response.GetResponseStream();
byte[] buffer = new byte[1024];
int bytesRead;
using MemoryStream memoryStream = new MemoryStream();
while ((bytesRead = responseStream.Read(buffer, 0, buffer.Length)) > 0)
{
memoryStream.Write(buffer, 0, bytesRead);
}
chunk.Data = memoryStream.ToArray();
});
using FileStream fs = new("C:\\Users\\Derpy\\Downloads\\" + fileName + Fcontenttype, FileMode.Create);
foreach (DownloadChunk chunk in chunks)
{
fs.Write(chunk.Data, 0, chunk.Data.Length);
}
}
private static DownloadChunk[] GetChunks(int parts, long totalsize)
{
DownloadChunk[] chunks = new DownloadChunk[parts];
long chunksize = totalsize / parts;
for (int i = 0; i < chunks.Length; i++)
{
chunks[i] = new()
{
Start = i == 0 ? 0 : chunksize = i + 1,
End = i == 0 ? chunksize : i == chunks.Length - 1 ? totalsize : chunksize * i + chunksize
};
}
return chunks;
}
}
}