WP7 IsolatedFileStorageStream - Wrong Byte size - c#

Using c#, I am downloading a file from a url the user enters on the phone. When it is writing the file to the IsolatedStorage, it is writing too many bytes to the file and therefore, the program used to open these files will not open.
When I debug, the bit size is 451,258 bytes, but when the file is exported from IsolatedStorage it is 454,656 bytes. It is filling the remaining space with spaces. Is there anyway to adjust this file size? Trim off the extra space at the end and save?
Forgive my ignorance as I am new at C# and WP7 developoment. I would really appreciate the help.
Here is my code :
public void readCompleteCallback(Object sender, OpenReadCompletedEventArgs e)
{
if (e.Error == null)
{
try
{
//string fileName = txtUrl.Text.Substring(txtUrl.Text.LastIndexOf("/") + 1).Trim();
string fileName = "DownloadedNZB.nzb";
bool isSpaceAvailable = IsSpaceIsAvailable(e.Result.Length);
if (isSpaceAvailable)
{
// Save mp3 to Isolated Storage
using (var isfs = new IsolatedStorageFileStream(fileName,
FileMode.CreateNew,
IsolatedStorageFile.GetUserStoreForApplication()))
{
long fileLen = e.Result.Length;
byte[] b = new byte[fileLen];
e.Result.Read(b, 0, b.Length);
isfs.Write(b, 0, b.Length);
isfs.Flush();
isfs.Close();
MessageBox.Show("File downloaded successfully");
}
}
else
{
MessageBox.Show("Not enough to save space available to download the file");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
else
{
MessageBox.Show(e.Error.Message);
}
}

Replace
e.Result.Read(b, 0, b.Length);
isfs.Write(b, 0, b.Length);
isfs.Flush();
isfs.Close();
with
var numberOfBytesRead = e.Result.Read(b, 0, b.Length);
isfs.Write(b, 0, numberOfBytesRead);
isfs.Flush();
isfs.Close();

Related

How to overcome slow-speeded FileSharing app across WLAN

After a lot more of study and research i was suggested on Stackoverflow to betterly use FileStream to open a file on client machine ,send file-name before sending data to server(listening at a pre-defined port),read a fixed-sized data in a buffer chunk-by-chunk ,send it to the remote server.All these operations were tested by me using various buffer-size starting from 10kb to 100MB now.I tested it for small-files and it worked nice.I went with the useful idea of sending 2GB file.it took almost an hour .
Following is the brief coded-idea.
Client-side:
try
{
clientSocket.Connect(new IPEndPoint(ipaddrcl, port));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
NetworkStream netstream = clientSocket.GetStream();
using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
{
try
{
TransmitFileName(netstream, Path.GetFileName(path));
int data_len = (int)fs.Length;
byte[] buffer = new byte[bufferSize];
int totalbytes = 0;
while (totalbytes < data_len)
{
var bytesread = fs.Read(buffer, 0, buffer.Length);
if (totalbytes == data_len)
{
break;
}
try
{
netstream.Write(buffer, 0, bytesread);
totalbytes += bytesread;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
pictureBox.Image = Properties.Resources.Warning;
labelProgress.Text = "Error in transmission";
}
}
}
finally
{
MessageBox.Show("Data transfer completed");
pictureBox.Image = Properties.Resources.Information;
labelProgress.Text = "Copying Done";
fs.Close();
netstream.Close();
// change button states
btnSend.Enabled = true;
btn_Cancel.Enabled = false;
}
}
Server-side:
Directory.CreateDirectory(Path.GetDirectoryName(fileloc));
try
{
using (FileStream fs = new FileStream(fileloc, FileMode.OpenOrCreate, FileAccess.Write))
{
netStream.CopyTo(fs);
pictureBox2.Image = Properties.Resources.spinningDisc1;
// label_server.Text = "Receiving Data";
}
}
catch (Exception e)
{
MessageBox.Show(e.Message.ToString());
}
finally
{
//check the size of file recieved
FileInfo fi = new FileInfo(fileloc);
long siz = fi.Length;
MessageBox.Show("Data Recieved: File Size is " + SizeSuffix(siz));
pictureBox2.Image = null;
// Thread();
}
In order to enhance speed ,i came across here and tested CopyFileEx for copying folders and trees on local-host and it worked superb.
Now the issue is,Can i use CopyFileEx on WLAN and if,yes, how will this ensures me to write a chunk-by-chunk piece of data and still ensures speedy process.
PS.I tried my best to not make it not so-lengthy but efforts are worth to show first before asking.I didn't find any working example for WLAN..if you have please give me a start-up with it.

Download a torrent file result is corrupt WP8

in an app I am making some of the files required are torrent files but i'm having an odd issue, whenever I download a torrent file through the app the files ends up corrupt and wont open in any torrent app, I used wptools to extract them to a pc and test it and still corrupt here is my code I can't see what 'im doing wrong, I am fairly new to using webclient. I assume it has something to do with the way im saving the file any help would be great thanks.
private void tbLink_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
string[] linkInfo = (sender as TextBlock).Tag as string[];
fileurl = linkInfo[0];
System.Diagnostics.Debug.WriteLine(fileurl);
WebClient client = new WebClient();
client.OpenReadCompleted += client_OpenReadCompleted;
client.OpenReadAsync(new Uri(fileurl), linkInfo);
client.AllowReadStreamBuffering = true;
}
async void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
string[] linkInfo = e.UserState as string[];
filetitle = linkInfo[1];
filesave = (filetitle);
var isolatedfile = IsolatedStorageFile.GetUserStoreForApplication();
using (IsolatedStorageFileStream stream = isolatedfile.OpenFile(filesave, System.IO.FileMode.Create))
{
byte[] buffer = new byte[e.Result.Length];
while (e.Result.Read(buffer, 0, buffer.Length) > 0)
{
stream.Write(buffer, 0, buffer.Length);
}
}
try
{
StorageFolder local = Windows.Storage.ApplicationData.Current.LocalFolder;
StorageFile torrentfile = await local.GetFileAsync(filesave);
Windows.System.Launcher.LaunchFileAsync(torrentfile);
}
catch (Exception)
{
MessageBox.Show("File Not Found");
}
This is incorrect:
byte[] buffer = new byte[e.Result.Length];
while (e.Result.Read(buffer, 0, buffer.Length) > 0)
{
stream.Write(buffer, 0, buffer.Length);
}
The Read method will return the number of bytes read, it can be less than buffer.Length. So the code should read:
int byteCount;
// Select an appropriate buffer size.
// This is a buffer, not space for the entire file.
byte[] buffer = new byte[4096];
while ((byteCount = e.Result.Read(buffer, 0, buffer.Length)) > 0)
{
stream.Write(buffer, 0, byteCount);
}
UPDATE: If the data is compressed, as in the question that you posted in your comment, then you can decompress the stream:
int byteCount;
byte[] buffer = new byte[4096];
using (GZipStream zs = new GZipStream(e.Result, CompressionMode.Decompress))
{
while ((byteCount = zs.Read(buffer, 0, buffer.Length)) > 0)
{
stream.Write(buffer, 0, byteCount);
}
}
Note that I have not tested this code, I'm assuming that e.Result is a stream.

Transferring files through sockets (bir and small sized)

Hello I'm trying to implement a server and client couple that can transfer files of any kind and any size but there is a problem I somehow corrupt files. I tried lots of methods but can't figure it out. So basicly I can connect ,I can understand which file does client want, and can send it through sockets. When I try to open that file it shows me an error message(Tried winrar, mp4, avi files) Here is my code:
//Server
private void Receive(string receivedFileName, string fileSize)
{
try
{
int receivedBytesLen = 0;
byte[] incomingFile = new byte[int.Parse(fileSize)];
activity.AppendText("Preparing to download... \n");
while (incomingFile != null && int.Parse(fileSize) > receivedBytesLen)
{
tempSocket.Receive(incomingFile);
receivedBytesLen = incomingFile.Length;
int fileNameLen = BitConverter.ToInt32(incomingFile, 0);
File.WriteAllBytes(fileDir + "//" + receivedFileName, incomingFile);
}
activity.AppendText("File saved to " + fileDir + "\n");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
//////////////////////////////////////////////////////////////////////
//server option 2
private void Receive(string receivedFileName, string fileSize)
{
try
{
byte[] incomingFile = new byte[10124 * 5000];
activity.AppendText("Preparing to download... \n");
BinaryWriter bWrite = new BinaryWriter(File.Open(folderBrowserDialog1.SelectedPath + "//" + receivedFileName, FileMode.Append));
int receivedBytesLen = tempSocket.Receive(incomingFile, incomingFile.Length, 0);
int fileNameLen = BitConverter.ToInt32(incomingFile, 0);
//string fileName = Encoding.UTF8.GetString(incomingFile, 4, fileNameLen);
//bWrite.Write(incomingFile, 4 + fileNameLen, receivedBytesLen - 4 - fileNameLen);
while (receivedBytesLen > 0)
{
receivedBytesLen = tempSocket.Receive(incomingFile, incomingFile.Length, 0);
if (receivedBytesLen == 0)
{
bWrite.Close();
}
else
{
bWrite.Write(incomingFile, 0, receivedBytesLen);
}
}
activity.AppendText("File saved to " + fileDir + "\n");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
/////////////////////////////////////////////////////////////////////
//client
private void Upload_Click(object sender, EventArgs e)
{//Uploads selected file after clicking upload button.
try
{
if (clientSocket.Connected)
{
byte[] buffer = new byte[1024];
byte[] sendingFile = null;
sendingFile = File.ReadAllBytes(openFileDialog1.FileName);
FileInfo f = new FileInfo(openFileDialog1.FileName);
string fileSize = f.Length.ToString();
buffer = Encoding.Default.GetBytes(getUserName.Text + "Upload" + openFileDialog1.SafeFileName + "size" + fileSize + "end");
clientSocket.Send(buffer);
activityLog.AppendText("Sending File \n");
int bytesToBeSent = sendingFile.Length;
int bytesActuallySent = 0;
while(bytesActuallySent < bytesToBeSent){
bytesActuallySent += clientSocket.Send(sendingFile, bytesActuallySent, bytesToBeSent -bytesActuallySent, 0);
}
activityLog.AppendText("File Sent.\n");
}
}
catch(Exception ex){
MessageBox.Show(ex.Message);
}
}
server option #2 is better. But there are some improvements
socket receive buffer is limited decided by OS, generally is 8192
use FileStream in client and server and do not forget to close filestream after file download
client:
FileStream fileStream = new FileStream(filePath, FileMode.Open)
byte[] buff = new byte[8192];
do
{
bytesRead = fileStream.Read(buff, 0, buff.Length);
sock.send(dataSock, buff, bytesRead);
}while (bytesRead > 0);
fileStream.close();
server:
FileStream fileStream = new FileStream(filePath, FileMode.Open)
do
{
bytesRead = sock.receive(buff, 0, buff.Lenght);
fileStream.Write(buff, 0, bytesRead );
}while (bytesRead > 0);
fileStream.close();
In order to satisfy ANY sized file you need an option #3, one that reads a block of bytes til all bytes are received, your option #1 wouldn't do so well on a 3 GIG file running on 2 GIG box...
Here is a link: http://www.yoda.arachsys.com/csharp/readbinary.html
I like option #2 from this link.
However in the example they write to a memoryStream, you should write to a filestream, the target file.

form turn to not responding after downloading a file from server

Its a very weird thing.
I created a client and a server to upload and download files. When uploading I can upload a lot of files without a problem but when I download a file the client for turn to not responding and doesn't show MessageBox.show("Downloaded"); its the first tie to see this :D.
The code that make the problem when used :
private void button3_Click(object sender, EventArgs e)
{
try
{
String fileToDownload = filePathDownload.Text;
TcpClient clientSocket = new TcpClient(serverIPDownload.Text, 8880);
NetworkStream networkStream = clientSocket.GetStream();
ASCIIEncoding asci = new ASCIIEncoding();
byte[] b = asci.GetBytes(fileToDownload + "?");
byte[] bb = asci.GetBytes("Download?");
int thisRead = 0;
int blockSize = 1024;
Byte[] dataByte = new Byte[blockSize];
networkStream.Write(bb, 0, bb.Length);
networkStream.Flush();
networkStream.Write(b, 0, b.Length);
networkStream.Flush();
using (FileStream fileStream = new FileStream(
"C:/Users/Laptop/Documents/Downloads/" + fileToDownload,
FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
{
while (true)
{
thisRead = networkStream.Read(dataByte, 0, blockSize);
fileStream.Write(dataByte, 0, thisRead);
if (thisRead == 0) break;
}
MessageBox.Show("File Downloaded");
fileStream.Close();
}
}
catch (Exception ex) { MessageBox.Show(ex.Message); }
}
Thanks. This maybe off topic but its the problem I faced.
Your code appears to be ok, so I suspect the problem is in the Download method you are reading from.
Also, I would personally move the loop termination (if (thisRead == 0) break;) before the fileStream.Write statement.
And for production code, I would add some sort of timeout limit so that you don't end up in an infinite loop.

SharpZipLib - ZipException "System.ArgumentOutOfRangeException" - Why am I getting this exception?

I'm using SharpZipLib to unzip files. My code has been working nicely for all zipfiles except the zip file what i am extracting now...
Got this exception:
System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
Parameter name: length
The exception is being thrown at size = s.Read(data, 0, data.Length);
Hereb is my code...
public static void UnzipFile(string sourcePath, string targetDirectory)
{
try
{
using (ZipInputStream s = new ZipInputStream(File.OpenRead(sourcePath)))
{
ZipEntry theEntry;
while ((theEntry = s.GetNextEntry()) != null)
{
//string directoryName = Path.GetDirectoryName(theEntry.Name);
string fileName = Path.GetFileName(theEntry.Name);
if (targetDirectory.Length > 0)
{
Directory.CreateDirectory(targetDirectory);
}
if (fileName != String.Empty)
{
using (FileStream streamWriter = File.Create(targetDirectory + fileName))
{
int size = 2048;
byte[] data = new byte[2048];
while (true)
{
size = s.Read(data, 0, data.Length);
if (size > 0)
{
streamWriter.Write(data, 0, size);
}
else
{
break;
}
}
}
}
}
}
}
catch (Exception ex)
{
throw new Exception("Error unzipping file \"" + sourcePath + "\"", ex);
}
}
Looks like a bug to me. Fortunately, you have access to the code, so you should be able to see exactly where it's going wrong. I suggest you build a debug version of SharpZipLib, break on the line which is throwing the exception, and have a look at what it's actually testing.
It should be fine to read into a 2K buffer even if there's not 2K of data left.
(I wouldn't actually write the code quite how you have, but that's a different matter. I'd also move it into its own utility method - the act of copying all the data from one stream to another is pretty common. There's no need to tie it to zip.)
Looking at the code, you are reading the same set of bytes again (and advancing the position).
size = s.Read(data, 0, data.Length);
An example from here shows that the 2nd argument should be a moving position & not a fixed number.
Change your code int size = 2048; to int size = data.Length;. You won't take OutOfRange exception.
using (FileStream streamWriter = File.Create(targetDirectory + fileName))
{
int size = data.Length;
byte[] data = new byte[size];
while (true)
{
size = s.Read(data, 0, data.Length);
if (size > 0)
{
streamWriter.Write(data, 0, size);
}
else
{
break;
}
}
}

Categories