Currently i am using following code , is there any better (means fast) way to upload a file, here is my complete code, it is called at each file upload:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("request_uri_string");
FileStream fileStream = new FileStream("path_to_my_file",
FileMode.Open, FileAccess.Read);
Stream requestStream = request.GetRequestStream();
byte[] buffer = new Byte[checked((uint)Math.Min(4096,
(int)fileStream.Length))];
int bytesRead = 1;
while (bytesRead != 0)
{
bytesRead = fileStream.Read(buffer, 0, buffer.Length);
if (bytesRead > 0)
{
requestStream.Write(buffer, 0, bytesRead);
}
}
requestStream.Close();
fileStream.Close();
String responseFromServer = null;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (((HttpWebResponse)response).StatusDescription.Contains("OK"))
{
Encoding encode = System.Text.Encoding.GetEncoding(((HttpWebResponse)response).CharacterSet);
Stream dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream, encode);
responseFromServer = reader.ReadToEnd();
reader.Close();
dataStream.Close();
}
response.Close();
Probably not faster, but easier:
WebClient client = new WebClient();
//client.Credentials = new NetworkCredential("username", "password");
client.UploadFile(uriString,fileName);
Related
I am using HttpWebRequest.GetStreamData() to get data from stream and then writing a couple of files in that variable.
Before calling the GetResponse() method on the stream, I need to get the copy of data and put it in text format.
Here's my code snippet
HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url);
wr.Method = "POST";
string requestbody = "Some Body Text"
Stream rs = wr.GetRequestStream();
foreach (fragment in Documents).ToList())
{
byte[] requestBytes = System.Text.Encoding.UTF8.GetBytes(requestbody);
rs.Write(requestBytes, 0, requestBytes.Length);
FileStream fileStream = new FileStream(fragment.FilePath, FileMode.Open, FileAccess.Read);
byte[] buffer = new byte[4096];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
rs.Write(buffer, 0, bytesRead);
}
fileStream.Flush();
fileStream.Close();
fileStream = null;
byte[] trailer = System.Text.Encoding.ASCII.GetBytes("Trailer Text");
rs.Write(trailer, 0, trailer.Length);
}
}
using (StreamReader strm = new StreamReader(rs))
{
string text = strm.ReadToEnd();
}
rs.Close();
rs = null;
The issue is I get error "stream was not readable".
When I check the property rs.canread, it is set to false.
Can anyone help me reading the content of my rs stream.
I have tried a couple of methods but none seems to be working as of now.
I have a simple function with I can upload a file via a webpage.
When I upload file with size 16 MB, it works, but if I try with a bigger file eg. 57 MB, the program throws
Stream was too long exception.
Stream memStream = new MemoryStream();
for (int i = 0; i < files.Length; i++)
{
memStream.Write(boundarybytes, 0, boundarybytes.Length);
var header = string.Format(headerTemplate, "uplTheFile", files[i]);
var headerbytes = Encoding.UTF8.GetBytes(header);
memStream.Write(headerbytes, 0, headerbytes.Length);
using (var fileStream = new FileStream(files, FileMode.Open, FileAccess.Read))
{
var buffer = new byte[fileStream.Length];
var bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
memStream.Write(buffer, 0, bytesRead);
}
}
}
memStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
request.ContentLength = memStream.Length;
using (Stream requestStream = request.GetRequestStream())
{
memStream.Position = 0;
byte[] tempBuffer = new byte[memStream.Length];
memStream.Read(tempBuffer, 0, tempBuffer.Length);
memStream.Close();
requestStream.Write(tempBuffer, 0, tempBuffer.Length);
}
using (var response = request.GetResponse())
{
Stream stream2 = response.GetResponseStream();
StreamReader reader2 = new StreamReader(stream2);
return reader2.ReadToEnd();
}
I initialize the request with that way.
HttpWebRequest request = HttpWebRequest.Create(url);
request.Timeout = 3600000;
request.Method = "POST";
request.KeepAlive = true;
So the server you are connecting to has the limits then ? In which case you can't upload it anyways right ?
for (int i = 0; i < files.Length; i++) was the problem.
I have tried to search for this issue else where in Stack Overflow but couldn't find a proper answer, hence posting my question here. Below is my code, basically i am trying to read content from a file and post it to a web api, and then repeat the same step with another file. The first call passes but the second call fails with the error:
The stream does not support concurrent IO read or write operations at this line requestStream.Write(buffer, 0, bytesRead);.
Could please tell me what am i doing wrong here?
using(FileStream fs = new FileStream(# "C:\Test1.txt", FileMode.Open, FileAccess.Read)) {
byte[] buffer = null;
int bytesRead = 0;
using(Stream requestStream = request.GetRequestStream()) {
buffer = new Byte[checked((uint) Math.Min(1024, (int) fs.Length))];
while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) != 0) {
requestStream.Write(buffer, 0, bytesRead);
}
requestStream.Flush();
}
}
using(FileStream fs = new FileStream(# "C:\Test2.txt", FileMode.Open, FileAccess.Read)) {
byte[] buffer = null;
int bytesRead = 0;
using(Stream requestStream = request.GetRequestStream()) {
buffer = new Byte[checked((uint) Math.Min(1024, (int) fs.Length))];
while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) != 0) {
requestStream.Write(buffer, 0, bytesRead);
}
requestStream.Flush();
}
}
I believe the problem is happening because you are trying to get a request stream that is no more avaliable:
Try this code:
List<string> files = new List<String>();
files.Add(#"C:\Test1.txt");
files.Add(#"C:\Test2.txt");
using (Stream requestStream = request.GetRequestStream())
{
files.ForEach(fileName =>
{
byte[] buffer = null;
int bytesRead = 0;
using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
buffer = new Byte[checked((uint)Math.Min(1024, (int)fs.Length))];
while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) != 0)
{
requestStream.Write(buffer, 0, bytesRead);
}
requestStream.Flush();
}
});
}
Update: To have control over endpoints and files, try this:
static void Main(string[] args)
{
string result = SendPost(#"C:\Test1.txt", "https://httpbin.org/post");
if(result.Contains("SUCCESS"))
SendPost(#"C:\Test2.txt", "https://httpbin.org/anotherpost");
}
static string SendPost(string filename, string URL)
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create(URL);
httpWebRequest.ContentType = "text/plain";
httpWebRequest.Method = "POST";
/*proxy config*/
WebProxy proxy = new WebProxy();
Uri newUri = new Uri("http://xxxxxx");
proxy.Address = newUri;
httpWebRequest.Proxy = proxy;
using (var sw = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string[] lines = File.ReadAllLines(filename);
for(int i=0; i<lines.Length; i++)
sw.WriteLine(lines[i]);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
return result;
}
}
I download a file with this method:
WebClient WC = new WebClient();
WC.DownloadFile(url, filePath);
And i want that in the same time to read the file in the same time with:
var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.None);
but i get allways :
The process cannot access the file 'filePath' because it is being used by another process.
It's possible to download and read in the same time?
Edit
I now download the file with:
var req = (HttpWebRequest)HttpWebRequest.Create(url);
var fileStream = new FileStream(filePath,
FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
using (var resp = req.GetResponse())
{
using (var stream = resp.GetResponseStream())
{
byte[] buffer = new byte[0x10000];
int len;
while ((len = stream.Read(buffer, 0, buffer.Length)) > 0)
{
fileStream.Write(buffer, 0, len);
}
}
}
And still get the error....
var req = (HttpWebRequest)HttpWebRequest.Create(url);
using (var resp = req.GetResponse())
{
using (var stream = resp.GetResponseStream())
{
byte[] buffer = new byte[0x10000];
int len;
while ((len = stream.Read(buffer, 0, buffer.Length))>0)
{
//Do with the content whatever you want
// ***YOUR CODE***
fileStream.Write(buffer, 0, len);
}
}
}
Try this way :
HttpWebRequest request = (HttpWebRequest) WebRequest.Create("http://www.domain.com/file.txt");
HttpWebResponse response = (HttpWebResponse) request.GetResponse();
var stream = response.GetResponseStream();
byte[] buffer = new byte[8192];
int bytesRead = 0;
while ((bytesRead = stream.Read(buffer, 0, 8192)) > 0)
{
// handle your raw data
// you needed raw data = buffer[0 to bytesRead - 1]
}
stream.Close();
response.Close();
I'm using VS 2010 (C#). I'm trying to encrypt (decrypt) a file as it is being uploaded (downloaded) from an FTP site. I thought this would be quicker than using a local temp file to encrypt before upload and decrypt after download. I get an error on the code below. I just can't seem to get the various stream types in alignment (i.e. FileStream, CryptoStream, and Stream). Any help is much appreciated.
public void Upload(byte[] desKey, byte[] desIV)
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(Destination);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(UserName, Password);
FileStream fStream = File.Open(SourceFile, FileMode.OpenOrCreate);
CryptoStream responseStream = new CryptoStream(fStream, new DESCryptoServiceProvider().CreateDecryptor(desKey, desIV), CryptoStreamMode.Read);
byte[] fileContents = Encoding.UTF8.GetBytes(responseStream.ToString());
responseStream.Close(); ///ERROR here
request.ContentLength = fileContents.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
response.Close();
}
Unit Test:
public void CleanEncryptUploadTest()
{
FT.ftp uploadTest = new FT.ftp();
uploadTest.UserName = "ausername";
uploadTest.Password = "apassword";
uploadTest.SourceFile = "D:\\Temp\\Test\\file.txt";
uploadTest.Destination = "ftp://ftp.mysite.com/test2.txt";
byte[] key = ASCIIEncoding.ASCII.GetBytes("TestZone");
byte[] initVector = ASCIIEncoding.ASCII.GetBytes("TestZone");
uploadTest.Upload(key, initVector);
}
This worked for me, I used a memory stream and wrote the encrypted bytes to it instead. Also changed the cryptostream mode to write.
public void Upload(byte[] key, byte[] iv)
{
byte[] fileContents;
using (FileStream inputeFile = new FileStream(this.SourceFile, FileMode.Open, FileAccess.Read))
{
using (MemoryStream encryptedStream = new MemoryStream())
{
using (CryptoStream cryptostream = new CryptoStream(encryptedStream, new DESCryptoServiceProvider().CreateEncryptor(key, iv), CryptoStreamMode.Write))
{
byte[] bytearrayinput = new byte[inputeFile.Length];
inputeFile.Read(bytearrayinput, 0, bytearrayinput.Length);
cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
fileContents = encryptedStream.ToArray();
}
}
}
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(this.Destination);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(this.UserName, this.Password);
request.ContentLength = fileContents.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
response.Close();
}