is there any way to get data from service to web api - c#

I am trying sending the data of file in chunks to web api through worker service. But chunks can not be received by web api, here is my code
Here is some code of worker service
int chunkSize = 100;
using (Stream streamx = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
byte[] buffer = new byte[chunkSize];
int bytesRead = 0;
long bytesToRead = streamx.Length;
while (bytesToRead > 0)
{
int n = streamx.Read(buffer, 0, chunkSize);
if (n == 0) break;
// Let's resize the last incomplete buffer
if (n != buffer.Length)
Array.Resize(ref buffer, n);
MultipartFormDataContent form = new MultipartFormDataContent();
HttpContent byteContent = new ByteArrayContent(buffer);
form.Add(byteContent, "fileByte");
HttpResponseMessage response1 = null;
try
{
response1 = client.PostAsync("http://localhost:15594/weatherforecast/PostData", form).Result;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
var k = response1.Content.ReadAsStringAsync().Result;
response = null;
bytesRead += n;
bytesToRead -= n;
}
Here is some code of web api
[HttpPost]
[Route("PostData")]
public IActionResult PostData()
{
var request = HttpContext.Request;
var vals = request.Form.TryGetValue("fileByte", out StringValues sv).ToString();
NameValueCollection vals2 = new NameValueCollection();
int count = vals2.Count;
string cv = null;
foreach(var i in vals2)
{
cv += i;
}
}

Here I have solved the issue, basically I want to upload a file in chunks ,
Here the code of file uploading to webapi ,
int chunkSize = 1024
using (Stream streamx = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
byte[] buffer = new byte[chunkSize];
int bytesRead = 0;
long bytesToRead = streamx.Length;
while (bytesToRead > 0)
{
int n = streamx.Read(buffer, 0, chunkSize);
if (n == 0) break;
if (n != buffer.Length)
Array.Resize(ref buffer, n);
MultipartFormDataContent multiContent = new MultipartFormDataContent();
ByteArrayContent bytes = new ByteArrayContent(buffer);
multiContent.Add(bytes, "file", fi.Name);
HttpResponseMessage response1 = null;
try
{
response1 = client.PostAsync("http://localhost:15594/weatherforecast/PostData", multiContent).Result;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
var k = response1.Content.ReadAsStringAsync().Result;
response = null;
bytesRead += n;
bytesToRead -= n;
}
}
'''
here is code snippet of webapi
'''
[HttpPost]
[Route("PostData")]
public IActionResult PostData()
{​​​​​​​
var form = Request.Form;
foreach (var formFile in form.Files)
{​​​​​​​
var fileName = formFile.FileName;
var savePath = Path.Combine(#"E:\Program\_210302_1WebApplication_API\_210302_1WebApplication_API\wwwroot", fileName);
using (var fileStream = new FileStream(savePath, FileMode.Append))
{​​​​​​​
formFile.CopyTo(fileStream);
}​​​​​​​
}​​​​​​​
}​​​​​​​
'''

Related

Async download file in c#

I need help to improve this code but I do not understand where I made a mistake. The file is downloaded but in a corrupted format. I am using cookies also which is a required part of this method.
/*Downlod task */
public static async Task<int> CreateDownloadTask(string urlToDownload,string sDestinationPath, string cookiedstr)
{
int BufferSize = 4096;
int receivedBytes = 0;
int totalBytes = 0;
WebClient client = new WebClient();
client.Headers.Add(HttpRequestHeader.Cookie, cookiedstr);
using (var stream = await client.OpenReadTaskAsync(urlToDownload))
{
using (MemoryStream ms = new MemoryStream())
{
int read = 0;
totalBytes = Int32.Parse(client.ResponseHeaders[HttpResponseHeader.ContentLength]);
var buffer = new byte[BufferSize];
while ((read = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
FileStream file = new FileStream(sDestinationPath, FileMode.Append, FileAccess.Write);
ms.Position = 0;
ms.WriteTo(file);
file.Flush();
file.Close();
buffer = new byte[BufferSize];
receivedBytes += read;
Console.WriteLine(receivedBytes + " " + totalBytes);
// DownloadBytesProgress args = new DownloadBytesProgress(urlToDownload, receivedBytes, totalBytes);
}
ms.Close();
}
return receivedBytes;
}
}

How to split file into parts and download

I'm working on a split downloader for c#. It is downloading fine (so the logic is working) but the problem is that whatever file it downloads it corrupts. I have no idea on how to fix it. Here's the code:
private void mergeClean()
{
const int chunkSize = 1 * 1024; // 2KB
using (var output = File.Create("output.jpg"))
{
foreach (var file in Files)
{
using (var input = File.OpenRead(file))
{
var buffer = new byte[chunkSize];
int bytesRead;
while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, bytesRead);
}
}
}
}
foreach (var file in Files)
{
File.Delete(file);
}
}
private void SaveFileStream(String path, Stream stream)
{
var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write);
stream.CopyTo(fileStream);
fileStream.Dispose();
}
public void SplitDownload(string URL)
{
System.Net.WebRequest req = System.Net.HttpWebRequest.Create(URL);
req.Method = "HEAD";
System.Net.WebResponse resp = req.GetResponse();
var responseLength = double.Parse(resp.Headers.Get("Content-Length"));
var partSize = Math.Ceiling(responseLength / 10);
var previous = 0;
for (int i = (int)partSize; i <= responseLength; i = i + (int)partSize)
{
Thread t = new Thread(() => Download(URL, previous, i));
t.Start();
t.Join();
previous = i;
}
mergeClean();
}
private void Download(string URL, int Start, int End)
{
Console.WriteLine(String.Format("{0},{1}", Start, End));
HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(URL);
myHttpWebRequest.AddRange(Start, End);
HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
Stream streamResponse = myHttpWebResponse.GetResponseStream();
String name = GenerateTempName();
SaveFileStream(name, streamResponse);
Files.Add(name);
}
Here is an example of what it does:
UPDATED CODE:
static string GenerateTempName(int start)
{
String name = String.Format("{0:D6}.tmp", start);
return name;
}
static public List<string> Files = new List<string>();
static private void mergeClean()
{
Files.Sort();
const int chunkSize = 1 * 1024; // 2KB
using (var output = File.Create("output.jpg"))
{
foreach (var file in Files)
{
using (var input = File.OpenRead(file))
{
var buffer = new byte[chunkSize];
int bytesRead;
while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, bytesRead);
}
}
}
}
foreach (var file in Files)
{
File.Delete(file);
}
}
You need to recombine file from pieces in correct order - current code create random file names and even if items are added to list of files they are added in random order due to unpredictable time when segment download finishes.
Possible fix: use block start offset as part of the file name String name = String.Format("file{0:D6}.tmp", Start) and sort files by name before combining them back.
Note that {0:D6} formatting is used to pad index with 0 to allow sorting by name to be easier and avoid need for natural sort code.

How do I zip files in Xamarin for Android?

I have a function that creates a zip file a string array of files passed. The function does succeed in creating the zip file and the zip entry files inside it, but these zip entry files are empty. I've tried a couple of different methods - the function code below is the closest I've gotten to something working:
public static bool ZipFile(string[] arrFiles, string sZipToDirectory, string sZipFileName)
{
if (Directory.Exists(sZipToDirectory))
{
FileStream fNewZipFileStream;
ZipOutputStream zos;
try {
fNewZipFileStream = File.Create(sZipToDirectory + sZipFileName);
zos = new ZipOutputStream(fNewZipFileStream);
for (int i = 0; i < arrFiles.Length; i++) {
ZipEntry entry = new ZipEntry(arrFiles[i].Substring(arrFiles[i].LastIndexOf("/") + 1));
zos.PutNextEntry(entry);
FileStream fStream = File.OpenRead(arrFiles[i]);
BufferedStream bfStrm = new BufferedStream(fStream);
byte[] buffer = new byte[bfStrm.Length];
int count;
while ((count = bfStrm.Read(buffer, 0, 1024)) != -1) {
zos.Write(buffer);
}
bfStrm.Close();
fStream.Close();
zos.CloseEntry();
}
zos.Close();
fNewZipFileStream.Close();
return true;
}
catch (Exception ex)
{
string sErr = ex.Message;
return false;
}
finally
{
fNewZipFileStream = null;
zos = null;
}
}
else
{
return false;
}
}
I think it's got to do with the byte stream handling. I've tried this bit of code that handles the stream but it goes into an infinite loop:
while ((count = fStream.Read(buffer, 0, 1024)) != -1) {
zos.Write(buffer, 0, count);
}
fStream.Close();
I found a solution that is quite simple - I used the ReadAllBytes method of the static File class.
ZipEntry entry = new ZipEntry(arrFiles[i].Substring(arrFiles[i].LastIndexOf("/") + 1));
zos.PutNextEntry(entry);
byte[] fileContents = File.ReadAllBytes(arrFiles[i]);
zos.Write(fileContents);
zos.CloseEntry();
Using Read() on a FileStream returns the amount of bytes read into the stream or 0 if the end of the stream has been reached. It will never return a value of -1.
From MSDN:
The total number of bytes read into the buffer. This might be less than the number of bytes requested if that number of bytes are not currently available, orzero if the end of the stream is reached.
I'd modify your code to the following:
System.IO.FileStream fos = new System.IO.FileStream(sZipToDirectory + sZipFileName, FileMode.Create);
Java.Util.Zip.ZipOutputStream zos = new Java.Util.Zip.ZipOutputStream(fos);
byte[] buffer = new byte[1024];
for (int i = 0; i < arrFiles.Length; i++) {
FileInfo fi = new FileInfo (arrFiles[i]);
Java.IO.FileInputStream fis = new Java.IO.FileInputStream(fi.FullName);
ZipEntry entry = new ZipEntry(arrFiles[i].Substring(arrFiles[i].LastIndexOf("/") + 1));
zos.PutNextEntry(entry);
int count = 0;
while ((count = fis.Read(buffer)) > 0) {
zos.Write(buffer, 0, count);
}
fis.Close();
zos.CloseEntry();
}
This is nearly identical to the code I've used for creating zip archives on Android in the past.
Are you allowed to use SharpZip? It's really easy to use.
Here is a blog post I wrote to extract zip files
private static void upzip(string url)
{
WebClient wc = new WebClient();
wc.DownloadFile(url, "temp.zip");
//unzip
ZipFile zf = null;
try
{
zf = new ZipFile(File.OpenRead("temp.zip"));
foreach (ZipEntry zipEntry in zf)
{
string fileName = zipEntry.Name;
byte[] buffer = new byte[4096];
Stream zipStream = zf.GetInputStream(zipEntry);
using (FileStream streamWriter = File.Create( fileName))
{
StreamUtils.Copy(zipStream, streamWriter, buffer);
}
}
}
finally
{
if (zf != null)
{
zf.IsStreamOwner = true;
zf.Close();
}
}
}
private void ZipFolder(string[] _files, string zipFileName)
{
using var memoryStream = new MemoryStream();
using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
{
foreach (var item in _files)
{
var demoFile = archive.CreateEntry(Path.GetFileName(item));
using var readStreamW = File.OpenRead(item);
using (var entryStream = demoFile.Open())
{
using (var streamWriter = new StreamWriter(entryStream))
{
readStreamW.Seek(0, SeekOrigin.Begin);
readStreamW.CopyTo(streamWriter.BaseStream);
}
}
}
}
using var fileStream = new FileStream(zipFileName, FileMode.Create);
memoryStream.Seek(0, SeekOrigin.Begin);
memoryStream.CopyTo(fileStream);
}

Can't get stable 304 response when caching in .NET

I need to control cache on the file-level.
Sometimes I can get a 304 response when the file is reloaded - but mostly not.
What am I doing wrong here with my caching settings?
public static void GetAndOutputFile(string url, int maxAgeInHours, string key)
{
Stream stream = null;
const int bytesToRead = 100000;
byte[] buffer = new Byte[bytesToRead];
try
{
HttpWebRequest fileReq = (HttpWebRequest) HttpWebRequest.Create(url);
HttpWebResponse fileResp = (HttpWebResponse) fileReq.GetResponse();
if (fileReq.ContentLength > 0)
fileResp.ContentLength = fileReq.ContentLength;
stream = fileResp.GetResponseStream();
var resp = HttpContext.Current.Response;
resp.ContentType = fileResp.ContentType;
//Set cache
resp.Cache.SetCacheability(HttpCacheability.Public);
resp.Cache.SetSlidingExpiration(false);
resp.Cache.SetLastModified(DateTime.Parse("1/1/2001 00:00:01AM"));
resp.Cache.SetMaxAge(TimeSpan.FromHours(maxAgeInHours));
resp.Cache.SetExpires(DateTime.UtcNow.AddHours(maxAgeInHours));
MemoryStream ms = new MemoryStream();
int length;
do
{
if (resp.IsClientConnected)
{
length = stream.Read(buffer, 0, bytesToRead);
resp.OutputStream.Write(buffer, 0, length);
ms.Write(buffer, 0, length);
resp.Flush();
buffer = new Byte[bytesToRead];
}
else
{
length = -1;
}
} while (length > 0); //Repeat until no data is read
}
finally
{
if (stream != null)
{
//Close the input stream
stream.Close();
stream.Dispose();
}
}
}
}
Found the solution. Key issue is that must set the 304 yourself in .NET.
public static void GetAndOutputFile(string url, int maxAgeInHours, string key)
{
if (!String.IsNullOrEmpty(HttpContext.Current.Request.Headers["If-Modified-Since"]))
{
CultureInfo provider = CultureInfo.InvariantCulture;
var lastMod = DateTime.ParseExact(HttpContext.Current.Request.Headers["If-Modified-Since"], "r", provider).ToLocalTime();
if (lastMod < DateTime.UtcNow.ToLocalTime())
{
HttpContext.Current.Response.StatusCode = 304;
HttpContext.Current.Response.StatusDescription = "Not Modified";
return;
}
}
Stream stream = null;
const int bytesToRead = 100000;
byte[] buffer = new Byte[bytesToRead];
try
{
HttpWebRequest fileReq = (HttpWebRequest)HttpWebRequest.Create(url);
HttpWebResponse fileResp = (HttpWebResponse)fileReq.GetResponse();
if (fileReq.ContentLength > 0)
fileResp.ContentLength = fileReq.ContentLength;
stream = fileResp.GetResponseStream();
var resp = HttpContext.Current.Response;
resp.ContentType = fileResp.ContentType;
resp.Cache.SetCacheability(HttpCacheability.Public);
resp.Cache.SetExpires(DateTime.UtcNow.AddHours(maxAgeInHours));
resp.Cache.SetLastModified(DateTime.UtcNow.AddMinutes(-1));
MemoryStream ms = new MemoryStream();
int length;
do
{
if (resp.IsClientConnected)
{
length = stream.Read(buffer, 0, bytesToRead);
resp.OutputStream.Write(buffer, 0, length);
ms.Write(buffer, 0, length);
resp.Flush();
buffer = new Byte[bytesToRead];
}
else
{
length = -1;
}
} while (length > 0); //Repeat until no data is read
}
finally
{
if (stream != null)
{
//Close the input stream
stream.Close();
stream.Dispose();
}
}

Receiving of multiple files using TCP-client

I want to create a TcpClient which automatically gets multiple files from server by their name.
I want to get some ideas how I can build such application.
My idea is:
Make a for loop which contains SwitchCase, where I specify my files names. I really don't know if this will work well.
To go out of for loop I can compare the index operator to numbers of files. If they are equal then I go out of for loop.
Example of my idea:
for (int i = 1; i <= 4; i++)
{
switch (----)
{
case 'file1':
code...
break;
case 'file2':
code...
case 'file3':
code...
break;
case 'file4':
code...
break;
default:
code...
break;
}
}
To download a file using ftp you could use the FtpWebRequest and for http use the HttpWebRequest.
Below is a simple example of how to request a file using http (the method is similar for ftp):
public void Download(string url, string localPath)
{
HttpWebRequest request = HttpWebRequest.Create(url);
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
Stream stream = response.GetResponseStream();
FileStream fs = new FileStream(localPath, FileMode.Create);
int count;
byte[] buffer = new byte[8096];
while ((count = stream.Read(buffer, 0, 8096)) > 0)
fs.Write(buffer, 0, count);
fs.Dispose();
response.Close();
}
Instead of using a switch inside a for loop you should iterate an array:
string[] files = new string[]{ url1, url2, ...};
for(int i = 0; i < files.Length; i++)
{
Download(files[i], "file" + i);
}
I solved it like so:
MY app. gets 2 files from server and move files and rename them.
test = mytest
test111 = test2
static string myfile1 = #"C:\inbox\mytest.txt";
static string myfile2 = #"C:\inbox\test2.txt";
//files from server
static string myServerfile = #"C:\Users\me\Documents\file_client\bin\Debug\test.csv";
static string myServerfile1 = #"C:\Users\RH-T3\Documents\file_client\bin\Debug\test111.txt";
public static void Main(string[] args)
{
try
{
for (int i = 0; i < 2; i++)
{
if (i == 0)
{
Console.WriteLine("Downloading test.csv");
string fileName = "test.csv";
Console.WriteLine("Client starts...");
//args[0] = Console.ReadLine();
file_client client = new file_client(args);
Console.WriteLine("efter file_client...");
NetworkStream serverStream = client.clientSocket.GetStream();
LIB.writeTextTCP(serverStream, fileName);
long rest = long.Parse(LIB.readTextTCP(serverStream));
byte[] inStream = new byte[rest];
while (rest != 0)
{
rest = rest - serverStream.Read(inStream, 0, inStream.Length);
Console.WriteLine("REST: " + rest);
}
FileStream fs = new FileStream(fileName, FileMode.Create);
fs.Write(inStream, 0, inStream.Length);
{
fs.Close();
serverStream.Close();
}
if (File.Exists(myfile1))
{
File.Delete(myfile1);
}
File.Move(myServerfile, myfile1);
Console.WriteLine("Moved");
System.Threading.Thread.Sleep(500);
}
else
{
Console.WriteLine("Downloading .txt file");
string fileName = "test111.txt";
Console.WriteLine("Client starts...");
//args[0] = Console.ReadLine();
file_client client = new file_client(args);
Console.WriteLine("efter file_client...");
NetworkStream serverStream = client.clientSocket.GetStream();
LIB.writeTextTCP(serverStream, fileName);
long rest = long.Parse(LIB.readTextTCP(serverStream));
byte[] inStream = new byte[rest];
while (rest != 0)
{
rest = rest - serverStream.Read(inStream, 0, inStream.Length);
Console.WriteLine("REST: " + rest);
}
FileStream fs = new FileStream(fileName, FileMode.Create);
fs.Write(inStream, 0, inStream.Length);
{
fs.Close();
serverStream.Close();
}
if (File.Exists(myfile2))
{
File.Delete(myfile2);
}
File.Move(myServerfile1, myfile2);
Console.WriteLine("Moved");
System.Threading.Thread.Sleep(500);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Console.WriteLine("Cannot be DONE!");
}

Categories

Resources