error 416 Requested Range Not Satisfiable in c# - c#

I am getting an error from the code below. Error 416 Requested Range Not Satisfiable in my custom DownloadFile method.
My file is a zip file with two pdf. This code is breaking for that specific file only. I am having 55 files out of which only one file is giving me this error. File are getting uploaded/downloaded to/from Azure Website Directory.
See the property window below of that file:
This is my code:
try
{
var packageId = updates[0];
var packagePath = updates[1];
var packageNameAvailable = Path.GetFileName(updates[1]);
log.Info($"Package id {packageId} | {packageNameAvailable} is available to download. ");
DownloadPackagePath = string.Format(#"{0}\{1}", ApiConfigHelper.PackageRootDirectory, packageNameAvailable);
var url = new Uri(updates[1]);
**DownloadFile(url.OriginalString, DownloadPackagePath);** // problem here
result = true;
}
catch (Exception ex)
{
log.Info("Error occurred while downloading package, stopping download. Cleaning up resources. ");
log.Error($"Error:{ex.Message}", ex);
log.Info("Cleaning up started....");
result = false;
}
DownloadFile Method:
private void DownloadFile(string sourceURL, string destinationPath)
{
long fileSize = 0;
int bufferSize = 1024;
bufferSize *= 1000;
long existLen = 0;
FileStream saveFileStream = null;
Stream resStream = null;
try
{
log.Info("Download started....");
if (File.Exists(destinationPath))
{
FileInfo destinationFileInfo = new FileInfo(destinationPath);
existLen = destinationFileInfo.Length;
log.Info($"Resuming partial downloaded file from {existLen / 1024} kB started....");
}
if (existLen > 0)
{
saveFileStream = new FileStream(destinationPath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
}
else
{
saveFileStream = new FileStream(destinationPath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
FileInfo destinationFileInfo = new FileInfo(destinationPath);
log.Info($"Starting download FileName:{destinationFileInfo.Name} Size: {destinationFileInfo.Length / 1024} kB ....");
}
var httpRequest = (HttpWebRequest)WebRequest.Create(sourceURL);
httpRequest.AddRange((int)existLen);
var httpResponse = (HttpWebResponse)httpRequest.GetResponse();
resStream = httpResponse.GetResponseStream();
fileSize = httpResponse.ContentLength;
int byteSize;
byte[] downBuffer = new byte[bufferSize];
while ((byteSize = resStream.Read(downBuffer, 0, downBuffer.Length)) > 0)
{
saveFileStream.Write(downBuffer, 0, byteSize);
}
log.Info("File downloaded successfully. Clean up started....");
}
catch
{
throw;
}
finally
{
log.Info("Cleaning up unused streams....");
if (saveFileStream != null)
{
saveFileStream.Close();
saveFileStream.Dispose();
}
if (resStream != null)
{
resStream.Close();
resStream.Dispose();
}
log.Info("DONE!!!");
}
}
Could you please help me identifying this.My log has an entry that says
Resuming partial downloaded file from 2494 kB started.... And stuck to that only.

Resuming partial downloaded file from 2494 kB started
Based on the log information, the request range is start from 2494 * 1024(2553856). 2,553,856 byte is larger than the file size(2,492,548) which can be seen from the file property window. The range of file which you request is not exist that will cause 416(Requested Range Not Satisfiable)error.
The reason may be that there is a exist file. It has a same name as the zip file which you want to download. Try to delete the exist file in the same folder will fix this issue.

Related

ICSharpCode.SharpZipLib Compression method not supported PKZIP

I have a problem with a zip-file created with the old PKZIPĀ® Command Line for Windows version 4 from the year 2000.
I am using ICSharpCode.SharpZipLib to extract the file.
Windows has no problem to open the file in the Explorer.
Here is the code:
private void Extract(string zipFile, string outputfolder)
{
try
{
_logger.InfoFormat("Extracting {0}", zipFile);
System.IO.Stream stream = new System.IO.FileStream(zipFile, System.IO.FileMode.Open);
ZipInputStream zipInputStream = new ZipInputStream(stream);
ZipEntry zipEntry = zipInputStream.GetNextEntry(); //Throws Compression error exception
while (zipEntry != null)
{
String entryFileName = zipEntry.Name;
_logger.InfoFormat("Entry-Filename: {0}", entryFileName);
byte[] buffer = new byte[4096];
String fullZipToPath = Path.Combine(outputfolder, entryFileName);
string directoryName = Path.GetDirectoryName(fullZipToPath);
if (directoryName.Length > 0)
{
Directory.CreateDirectory(directoryName);
}
using (FileStream streamWriter = File.Create(fullZipToPath))
{
StreamUtils.Copy(zipInputStream, streamWriter, buffer);
}
zipEntry = zipInputStream.GetNextEntry();
}
}
catch (Exception ex)
{
_logger.Error("Error during extraction",ex);
throw;
}
}
Any idea how to fix this problem?
I had this same issue when decompressing a zip-file made with 7-zip.
I changed it from Deflate64 to Deflate, and then it worked.

Opening large files

I have a processes I made that has been working well for several months now. The process recursively zips up all files and folders in a given directory and then uploads the zip file to an FTP server. Its been working, but now, the zip file is exceeding 2gb and its erroring out. Can someone please help me figure out how to get around this 2gb limit? I commented the offending line in the code. Here is the code:
class Program
{
// Location of upload directory
private const string SourceFolder = #"C:\MyDirectory";
// FTP server
private const string FtpSite = "10.0.0.1";
// FTP User Name
private const string FtpUserName = "myUserName";
// FTP Password
private const string FtpPassword = "myPassword";
static void Main(string[] args)
{
try
{
// Zip everything up using SharpZipLib
string tmpFile = Path.GetTempFileName();
var zip = new ZipOutputStream(File.Create(tmpFile));
zip.SetLevel(8);
ZipFolder(SourceFolder, SourceFolder, zip);
zip.Finish();
zip.Close();
// Upload the zip file
UploadFile(tmpFile);
// Delete the zip file
File.Delete(tmpFile);
}
catch (Exception ex)
{
throw ex;
}
}
private static void UploadFile(string fileName)
{
string remoteFileName = "/ImagesUpload_" + DateTime.Now.ToString("MMddyyyyHHmmss") + ".zip";
var request = (FtpWebRequest)WebRequest.Create("ftp://" + FtpSite + remoteFileName);
request.Credentials = new NetworkCredential(FtpUserName, FtpPassword);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.KeepAlive = false;
request.Timeout = -1;
request.UsePassive = true;
request.UseBinary = true;
// Error occurs in the next line!!!
byte[] b = File.ReadAllBytes(fileName);
using (Stream s = request.GetRequestStream())
{
s.Write(b, 0, b.Length);
}
using (var resp = (FtpWebResponse)request.GetResponse())
{
}
}
private static void ZipFolder(string rootFolder, string currentFolder, ZipOutputStream zStream)
{
string[] subFolders = Directory.GetDirectories(currentFolder);
foreach (string folder in subFolders)
ZipFolder(rootFolder, folder, zStream);
string relativePath = currentFolder.Substring(rootFolder.Length) + "/";
if (relativePath.Length > 1)
{
var dirEntry = new ZipEntry(relativePath) {DateTime = DateTime.Now};
}
foreach (string file in Directory.GetFiles(currentFolder))
{
AddFileToZip(zStream, relativePath, file);
}
}
private static void AddFileToZip(ZipOutputStream zStream, string relativePath, string file)
{
var buffer = new byte[4096];
var fi = new FileInfo(file);
string fileRelativePath = (relativePath.Length > 1 ? relativePath : string.Empty) + Path.GetFileName(file);
var entry = new ZipEntry(fileRelativePath) {DateTime = DateTime.Now, Size = fi.Length};
zStream.PutNextEntry(entry);
using (FileStream fs = File.OpenRead(file))
{
int sourceBytes;
do
{
sourceBytes = fs.Read(buffer, 0, buffer.Length);
zStream.Write(buffer, 0, sourceBytes);
} while (sourceBytes > 0);
}
}
}
You are trying to allocate an array possessing more than 2billion elements. .NET limits the maximum size of an array is System.Int32.MaxValue i.e. 2Gb is the upper bound.
You're better off reading the file in pieces an uploading it in pieces; e.g using a loop reading:
int buflen = 128 * 1024;
byte[] b = new byte[buflen];
FileStream source = new FileStream(fileName, FileMode.Open);
Stream dest = request.GetRequestStream();
while (true) {
int bytesRead = source.Read(buf, 0, buflen);
if (bytesRead == 0) break;
dest.Write(buf, 0, bytesRead);
}
The problem isn't in the zip, but in the File.ReadAllBytes call, which returns an array which has the default size limit of 2GB.
It is possible to disable this limit, as detailed here. I'm assuming you're already compiling this specifically for 64 bit to handle these kind of file sizes. Enabling this option switches .NET over to using 64 bit addresses for arrays instead of the default 32 bit addresses.
It would probably be better to split the archive into parts and upload them separately however. As far as I know the built in ZipFile class doesn't support multi-part archives, but several of the third party libraries do.
Edit: I was thinking about the resulting zip output, rather than the input. To load a huge amount of data INTO the ZipFile, you should use the Buffer based approach suggested by Petesh and philip.

uploading a file using WCF in ASP.NET

I have created one WCF service that will upload the file. and after using that service I am trying to upload the file I am able to successfully upload the file but there is some issue with the FILESTREAM class.
The moment i clicked the button to upload the file when i checked by debugging the application i get to know that stream object is null.
I am passing the object of stream class to the WCF method.
But due to some issue that stream object is getting null.
due to that null object of stream class, image which is uploded getting empty in my folder
This is my code that I am using to upload the file
if (FileUpload1.HasFile)
{
System.IO.FileInfo fileInfo = new System.IO.FileInfo(FileUpload1.PostedFile.FileName);
FileTransferServiceReference.ITransferService clientUpload = new FileTransferServiceReference.TransferServiceClient("BasicHttpBinding_ITransferService");
FileTransferServiceReference.RemoteFileInfo uploadRequestInfo = new RemoteFileInfo();
string Path = System.IO.Path.GetDirectoryName(FileUpload1.FileName);
using (System.IO.FileStream stream = new System.IO.FileStream(FileUpload1.FileName, System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
uploadRequestInfo.FileName = FileUpload1.FileName;
uploadRequestInfo.Length = fileInfo.Length;
uploadRequestInfo.FileByteStream = stream;
clientUpload.UploadFile(uploadRequestInfo);
}
}
Code for WCF Service
public RemoteFileInfo DownloadFile(DownloadRequest request)
{
RemoteFileInfo result = new RemoteFileInfo();
try
{
// get some info about the input file
string filePath = System.IO.Path.Combine(#"c:\Uploadfiles", request.FileName);
System.IO.FileInfo fileInfo = new System.IO.FileInfo(filePath);
// check if exists
if (!fileInfo.Exists) throw new System.IO.FileNotFoundException("File not found", request.FileName);
// open stream
System.IO.FileStream stream = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read);
// return result
result.FileName = request.FileName;
result.Length = fileInfo.Length;
result.FileByteStream = stream;
}
catch (Exception ex)
{
}
return result;
}
public void UploadFile(RemoteFileInfo request)
{
FileStream targetStream = null;
Stream sourceStream = request.FileByteStream;
string uploadFolder = #"C:\upload\";
if (!Directory.Exists(uploadFolder))
{
Directory.CreateDirectory(uploadFolder);
}
string filePath = Path.Combine(uploadFolder, request.FileName);
using (targetStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None))
{
const int bufferLen = 65000;
byte[] buffer = new byte[bufferLen];
int count = 0;
while ((count = sourceStream.Read(buffer, 0, bufferLen)) > 0)
{
targetStream.Write(buffer, 0, count);
}
targetStream.Close();
sourceStream.Close();
}
}
}
Spot the difference:
string uploadFolder = #"C:\upload\";
...
string filePath = System.IO.Path.Combine(#"c:\Uploadfiles", request.FileName);
As a general tip you might put your upload file path into an external configuration file, so that you can change it when you move your application onto a server where you need to store the data on a different drive or in a specific location.
Also that way you are always calling the same configuration entry so your upload path name is definitely going to be the same everywhere.

Error on making resumeable download in c#

I was trying to test a resumable download using c#. I found that add range will help by looking at some blogs. But in the following code add range have no meaning.
Guys Suggest me how to solve the issue.
What method will be effective to make a Resumable download??
HttpWebRequest myrequest = null;
HttpWebResponse myresponse = null;
private int interval=2048;
public bool set_url(string todonwloads,string tosaves)
{
this.todownload = todonwloads;
this.tosave = tosaves;
return true;
}
public bool start_download()
{
myrequest = (HttpWebRequest)WebRequest.Create(this.todownload);
// it the following code.
//If i dont write addrange. It will download same portion of the file.
myrequest.AddRange(4000,8000);
try
{
myresponse = (HttpWebResponse)myrequest.GetResponse();
if (myresponse.StatusCode == HttpStatusCode.OK)
{
Stream ReceiveSteam = myresponse.GetResponseStream();
FileStream fs = new FileStream(
this.tosave,
FileMode.Create,
FileAccess.Write,
FileShare.None);
int reads;
byte[] buffer = new byte[this.interval];
while ((reads = ReceiveSteam.Read(
buffer,
0,
this.interval)) > 0)
{
fs.Write(buffer, 0, reads);
}
return true;
}
}
catch (WebException ex)
{
throw ex;
}
finally
{
if (myresponse != null)
{
myresponse.Close();
}
}
return false;
}
You currently create and overwrite the file every time you download a section of the file:
// Overwrites the file each time -\/
... = new FileStream(this.tosave, FileMode.Create, ...
You instead need to open or create the file using FileMode.OpenOrCreate, then seek to the last section of the file you wrote to:
// seek to the last end offset, you'll need to save this somehow
fs.Seek(lastOffset, SeekOrigin.Begin);
int reads;
byte[] buffer = new byte[this.interval];
while ((reads = ReceiveSteam.Read(buffer, 0, this.interval)) > 0)
{
fs.Write(buffer, 0, reads);
lastOffset += reads;
}

Program hangs on FtpWebResponse

First time poster, long-time reader. I have a really annoying problem thats been getting on my nerves. Ive got a program set up so I listen for new files on an FTP server, if theres a new file I download it. From there I work on some of the information in the file, etc. My problem comes when I run through my sequence the second time. That is, on the first file I download everything is totally fine, but as soon as a new file gets detected and my program tries downloading it, my program just hangs.
private static void DownloadFile(string s)
{
try
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://blabla.com/"+s);
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.Credentials = new NetworkCredential("xxx" ,"zzz");
using (FtpWebResponse partResponse = (FtpWebResponse)request.GetResponse())
{
Stream partReader = partResponse.GetResponseStream();
byte[] buffer = new byte[1024];
FileInfo fi = new FileInfo(path);
FileStream memStream = fi.Create();
while (true)
{
int bytesRead = partReader.Read(buffer, 0, buffer.Length - 1);
if (bytesRead == 0)
break;
memStream.Write(buffer, 0, bytesRead);
}
partResponse.Close();
memStream.Close();
}
Console.WriteLine(DateTime.Now + " file downloaded");
MoveFileToInProgress(s);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
The line it hangs on is this one:
using (FtpWebResponse partResponse = (FtpWebResponse)request.GetResponse())
The reason my method here is static is because Im just running it in a different project to test it.. My question here is, how come it only ever dies on the second file? Ive been staring myself blind for hours now!
I ran into this problem as well... try finishing your request first and then closing it before trying to retrieve the response. That worked for me (actually tried it after reading comment by MartinNielsen). Here is what I did.
// connect to the ftp site
FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(ftpUri);
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
ftpRequest.Credentials = new NetworkCredential(ftpUser, ftpPassword);
// setting proxy to null so that it does not go through the proxy
ftpRequest.Proxy = null;
// get file information
StreamReader fileStream = new StreamReader(filePath);
byte[] fileBytes = Encoding.UTF8.GetBytes(fileStream.ReadToEnd());
ftpRequest.ContentLength = fileBytes.Length;
fileStream.Close();
// open connection to ftp site
Stream ftpRequestStream = ftpRequest.GetRequestStream();
// write the file to the stream
ftpRequestStream.Write(fileBytes, 0, fileBytes.Length);
// close the stream
ftpRequestStream.Close();
// get the response from the server
FtpWebResponse ftpUploadResponse = (FtpWebResponse)ftpRequest.GetResponse();
string result = ftpUploadResponse.StatusDescription;
// close response
ftpUploadResponse.Close();
// return response to calling code
return result;
Here are a couple of the resources that I used when writing this code (won't let me post more than 2, there were more)
How to: Upload Files with FTP
Uploading a file -- "The requested URI is invalid for this FTP command"
I'm not expert on C# but I use this code to download files from my ftp:
public void Download(string filename)
{
// I try to download five times before crash
for (int i = 1; i < 5; i++)
{
try
{
FtpWebRequest ftp = (FtpWebRequest)FtpWebRequest.Create(Global.Path + "/" + filename);
ftp.Credentials = new NetworkCredential(User, Pass);
ftp.KeepAlive = false;
ftp.Method = WebRequestMethods.Ftp.DownloadFile;
ftp.UseBinary = true;
ftp.Proxy = null;
int buffLength = 2048;
byte[] buff = new byte[buffLength];
int contentLen;
string LocalDirectory = Application.StartupPath.ToString() + "/downloads/" + filename;
using (FileStream fs = new FileStream(LocalDirectory, FileMode.Create, FileAccess.Write, FileShare.None))
using (Stream strm = ftp.GetResponse().GetResponseStream())
{
contentLen = strm.Read(buff, 0, buffLength);
while (contentLen != 0)
{
fs.Write(buff, 0, contentLen);
contentLen = strm.Read(buff, 0, buffLength);
}
}
Process.Start(LocalDirectory);
break;
}
catch (Exception exc)
{
if (i == 5)
{
MessageBox.Show("Can't download, try number: " + i + "/5 \n\n Error: " + exc.Message,
"Problem downloading the file");
}
}
}
}
Tell me if it works for you :)

Categories