Filestream.readtimeout: invalid operation exception - c#

I want to download file (.PDF as an example) using File stream. Here is a contrived example:
public ActionResult GetPDF()
{
ActionResult ar = null;
FileStream fs = null;
try
{
fs = System.IO.File.OpenRead(filename);
var bytes = new byte[fs.Length];
var x = fs.Read(bytes, 0, Convert.ToInt32(fs.Length));
abcd fr = new abcd(fs, "application/pdf");
}
catch(Exception)
{
}
return ar;
}
public class CheckedFileStreamResult : FileStreamResult
{
public bool DownloadCompleted { get; set; }
public CheckedFileStreamResult(FileStream stream, string contentType)
: base(stream, contentType)
{
DownloadCompleted = false;
}
protected override void WriteFile(HttpResponseBase response)
{
var outputStream = response.OutputStream;
response.BufferOutput = false;
using (FileStream)
{
var buffer = new byte[_bufferSize];
var count = FileStream.Read(buffer, 0, _bufferSize);
while (count != 0 && response.IsClientConnected)
{
outputStream.Write(buffer, 0, count);
count = FileStream.Read(buffer, 0, _bufferSize);
}
DownloadCompleted = response.IsClientConnected;
}
}
private const int _bufferSize = 0x1000;
}
public class abcd : CheckedFileStreamResult
{
public abcd(FileStream stream, string contentType) : base(stream, contentType)
{
DownloadCompleted = false;
}
public void Write(HttpResponseBase response)
{
WriteFile(response);
}
}
I always get count with value 0. Invalid Operation Exception is thrown here:
var count = FileStream.Read(buffer, 0, _bufferSize);
Please guide me how can I proceed. I want to know whether the file was downloaded successfully.

Related

How to create a MemoryStream packet and extract relevant data from NetworkStream?

I've created packetReader & packetBuilder for passing and receiving packets that contain string message (using TcpClient and TcpListener in the server)
and I'm trying to do the same with byte[].
Here is how the message packet is built :
How to implement the same WriteCanvasStrokes() and ReadCanvasStrokes() ?
Here is how I send to server:
TcpClient _client;
public void SendMessageToServer(string message)
{
var messagePacket = new PacketBuilder();
messagePacket.WriteOpCode(5);
messagePacket.WriteMessage(message);
_client.Client.Send(messagePacket.GetPacketBytes());
}
public void SendCanvasStrokesToServer(MemoryStream memoryStream)
{
var strokesPacket = new PacketBuilder();
strokesPacket.WriteOpCode(7);
strokesPacket.WriteCanvasStrokes(memoryStream.GetBuffer());
_client.Client.Send(strokesPacket.GetPacketBytes());
}
PacketBuilder :
public class PacketBuilder
{
MemoryStream _ms;
public PacketBuilder()
{
_ms = new MemoryStream();
}
public void WriteOpCode(byte opcode)
{
_ms.WriteByte(opcode);
}
public void WriteMessage(string msg)
{
var msgLength = msg.Length;
_ms.Write(BitConverter.GetBytes(msgLength));
_ms.Write(Encoding.ASCII.GetBytes(msg));
}
public void WriteCanvasStrokes(byte[] strokes)
{
_ms.Write(BitConverter.GetBytes(strokes.Length));
_ms.Write(strokes);
}
public Byte[] GetPacketBytes()
{
return _ms.ToArray();
}
}
PacketReader :
public class PacketReader : BinaryReader
{
private NetworkStream _ns;
public PacketReader(NetworkStream ns) : base(ns)
{
_ns = ns;
}
public string ReadMessage()
{
byte[] msgBuffer;
var length = ReadInt32();
msgBuffer = new byte[length];
_ns.Read(msgBuffer, 0, length);
var msg = Encoding.ASCII.GetString(msgBuffer);
return msg;
}
public byte[] ReadCanvasStrokes()
{
byte[] strokesBuffer;
var length = ReadInt32();
strokesBuffer = new byte[length];
_ns.Read(strokesBuffer, 0, length);
return strokesBuffer;
}
}

how to write json file with size limit (100KB) and once size cross, write new file?

I have a blocking collection which gets filled with data by some app1.
I have subscribed to that blocking collection and need to write a file with below case,
start writing a file .
if the file size crossed 100kb, close the first file and starts a new file.
and if there is no data coming from app1, lets say for 1 minute, then close the file.
Currently with below code, I'm only able to write per blocking collection into per file, how to proceed with my above requirement, please suggest.
class Program
{
private static BlockingCollection<Message> messages = new BlockingCollection<Message>();
private static void Producer()
{
int ctr = 1;
while (true)
{
messages.Add(new Message { Id = ctr, Name = $"Name-{ctr}" });
Thread.Sleep(1000);
ctr++;
}
}
private static void Consumer()
{
foreach (var message in messages.GetConsumingEnumerable())
{
Console.WriteLine(JsonConvert.SerializeObject(message));
using (var streamWriter = File.CreateText(Path.Combine(#"C:\TEMP", $"File-{ DateTime.Now.ToString("yyyyMMddHHmmssfff")}.json")))
{
using (var writer = new JsonTextWriter(streamWriter))
{
writer.Formatting = Formatting.Indented;
writer.WriteStartObject();
writer.WritePropertyName("Data");
writer.WriteStartArray();
writer.WriteRawValue(JsonConvert.SerializeObject(message));
writer.WriteEndArray();
writer.WriteEndObject();
}
}
}
}
static void Main(string[] args)
{
var producer = Task.Factory.StartNew(() => Producer());
var consumer = Task.Factory.StartNew(() => Consumer());
Console.Read();
}
}
This will take the messages with any size and divided it to a different JSON file. You need to specify the size using maxchar. before that, you have to check the size of the last file like this and you have to pass the same file name and the new size if else create a new file and divide the message.
using System;
using System.IO;
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Concurrent;
using System.Collections;
using Newtonsoft.Json;
using System.Runtime.Remoting.Messaging;
using System.Text;
namespace Program
{
class Program
{
public static string last_path = "";
public static readonly string BYE = "bye";
private static BlockingCollection<Message> messages = new BlockingCollection<Message>();
private static void Producer()
{
int ctr = 1;
while (true)
{
messages.Add(new Message { Id = ctr, Name = $"Name-{ctr}" });
Thread.Sleep(1000);
ctr++;
}
}
private static void Consumer()
{
foreach (var message in messages.GetConsumingEnumerable())
{
Console.WriteLine(JsonConvert.SerializeObject(message));
string json = JsonConvert.SerializeObject(message);
int maxchar = 102400;
if (last_path != "")
{
long length = new FileInfo(last_path).Length;
if (length < maxchar)
{
maxchar = maxchar - unchecked((int)length);
dividefile(last_path, maxchar, json);
}
else
{
dividefile("", maxchar, json);
}
}
else
{
dividefile("", maxchar, json);
}
}
}
public static void dividefile(string path, int maxchar, string message)
{
//FileStream fileStream = new FileStream(yourfile, FileMode.Open, FileAccess.Read);
byte[] byteArray = Encoding.UTF8.GetBytes(message);
MemoryStream stream = new MemoryStream(byteArray);
using (StreamReader streamReader = new StreamReader(stream))
{
Int64 x1 = stream.Length;
char[] fileContents = new char[maxchar];
int charsRead = streamReader.Read(fileContents, 0, maxchar);
// Can't do much with 0 bytes
if (charsRead == 0)
throw new Exception("File is 0 bytes");
while (charsRead > 0)
{
x1 = x1 - maxchar;
if (x1 > 0)
{
string s = new string(fileContents);
if (path == "")
{
last_path = Path.Combine(#"C:\TEMP", $"File-{ DateTime.Now.ToString("yyyyMMddHHmmssfff")}.json");
path = "";
}
else
{
last_path = path;
}
AppendTransaction(last_path, s);
charsRead = streamReader.Read(fileContents, 0, maxchar);
}
else
{
int m = (int)(((x1 + maxchar) % maxchar));
string messagechunk = new string(fileContents, 0, m);
if (path == "")
{
last_path = Path.Combine(#"C:\TEMP", $"File-{ DateTime.Now.ToString("yyyyMMddHHmmssfff")}.json");
path = "";
}
else
{
last_path = path;
}
AppendTransaction(last_path, messagechunk);
charsRead = streamReader.Read(fileContents, 0, m);
}
}
}
}
private static void AppendTransaction(string path , string transaction)
{
string filename = path;
bool firstTransaction = !File.Exists(filename);
JsonSerializer ser = new JsonSerializer();
ser.Formatting = Formatting.Indented;
ser.TypeNameHandling = TypeNameHandling.Auto;
using (var fs = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read))
{
Encoding enc = firstTransaction ? new UTF8Encoding(true) : new UTF8Encoding(false);
using (var sw = new StreamWriter(fs, enc))
using (var jtw = new JsonTextWriter(sw))
{
if (firstTransaction)
{
sw.Write("[");
sw.Flush();
}
else
{
fs.Seek(-Encoding.UTF8.GetByteCount("]"), SeekOrigin.End);
sw.Write(",");
sw.Flush();
}
ser.Serialize(jtw, transaction);
sw.Write(']');
}
}
}
static void Main(string[] args)
{
var producer = Task.Factory.StartNew(() => Producer());
var consumer = Task.Factory.StartNew(() => Consumer());
Console.Read();
}
class Message
{
public int ProductorThreadID { get; set; }
public int CustomerThreadID { get; set; }
public string key { get; set; }
public string content { get; set; }
public string Name { get; internal set; }
public int Id { get; internal set; }
public bool endThread()
{
return string.Compare(key, Program.BYE) == 0;
}
public string ToString(bool isProductor)
{
return string.Format("{0} Thread ID {1} : {2}", isProductor ? "Productor" : "Customer",
isProductor ? ProductorThreadID.ToString() : CustomerThreadID.ToString(),
content);
}
}
}
}

UWP with UDP StreamWriter in OSC format

I have following class take care the udp Sending
public static async Task SendStringUdpAsync(HostName remoteHost,
string remotePort, string message)
{
using (var socket = new DatagramSocket())
{
var stream = (await socket.GetOutputStreamAsync(
remoteHost, remotePort)).AsStreamForWrite();
using (var writer = new StreamWriter(stream))
{
await writer.WriteLineAsync(message.ToString());
await writer.FlushAsync();
}
}
}
But instead send a string, I want to send a custom class in udp
public class OSCString : IOSCValue<string>
{
static int PaddingLength = 4;
public string Contents { get; }
public char TypeTag { get { return 's'; }}
public byte[] Bytes { get; }
public OSCString(string contents)
{
Contents = contents;
Bytes = GetBytes();
}
public byte[] GetBytes()
{
byte[] bytes = new byte[GetByteLength()];
Encoding.ASCII.GetBytes(Contents, 0, Contents.Length, bytes, 0);
return bytes;
}
public int GetByteLength()
{
return GetPaddedLength(Contents.Length);
}
public static int GetPaddedLength(int length)
{
int terminatedLength = length + 1;
int paddedLength = (int)(Math.Ceiling(terminatedLength / (float)PaddingLength) * 4);
return paddedLength;
}
public static OSCString Parse(BinaryReader reader)
{
List<byte> bytes = new List<byte>();
byte current = reader.ReadByte();
while(current != 0)
{
bytes.Add(current);
current = reader.ReadByte();
}
string str = Encoding.ASCII.GetString(bytes.ToArray());
OSCString oscString = new OSCString(str);
int bytesToBurn = oscString.Bytes.Length - bytes.Count - 1;
for(int i = 0; i < bytesToBurn; i++)
{
reader.ReadByte();
}
return oscString;
}
}
I try DataWriter and StreamWrite, dont work too well.
The UWP take out the socket class, is there any Streamwrite can do the job?
I figure this out
var socket = new DatagramSocket();
//socket.MessageReceived += SocketOnMessageReceived;
using (var stream = await socket.GetOutputStreamAsync(remoteHost, remotePort))
{
using (var writer = new DataWriter(stream))
{
// var data = Encoding.UTF8.GetBytes(message);
writer.WriteBytes(packet.Bytes);
writer.StoreAsync();
}
}
Everything works great!!!!!!!!!

Xamarin.Forms PCL SQLiteException: file is encrypted or is not a database and 'Resource' does not contain a definition for 'Raw'

Today I am facing with this issue: I got such a exception :
SQLite.SQLiteException: file is encrypted or is not a database
I am doing project regarding this guide: https://developer.xamarin.com/guides/xamarin-forms/working-with/databases/ .
This is my Database class where I am initialize Connection and Table creation:
public class ThingDatabase
{
SQLiteConnection database;
public ThingDatabase()
{
database = DependencyService.Get<ISQLite>().GetConnection();
database.CreateTable<ThingObj>();
}
}
Here is my object class:
public class ThingObj
{
public ThingObj()
{
}
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string City { get; set; }
public string ThingNumber { get; set; }
public bool IsStarted { get; set; }
}
And here is my created SQLite_Android class regarding example:
[assembly: Dependency(typeof(SQLite_Android))]
...
{
public class SQLite_Android : ISQLite
{
public SQLite_Android() { }
public SQLite.SQLiteConnection GetConnection() {
var sqliteFilename = "ThingSQLite.db3";
string documentsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
var path = Path.Combine(documentsPath, sqliteFilename);
Console.WriteLine(path);
if (!File.Exists(path))
{
var s = Forms.Context.Resources.OpenRawResource(Resource.Raw.Database);
FileStream writeStream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write);
ReadWriteStream(s, writeStream);
}
var conn = new SQLite.SQLiteConnection(path);
return conn;
}
void ReadWriteStream(Stream readStream, Stream writeStream)
{
int Length = 256;
Byte[] buffer = new Byte[Length];
int bytesRead = readStream.Read(buffer, 0, Length);
while (bytesRead > 0)
{
writeStream.Write(buffer, 0, bytesRead);
bytesRead = readStream.Read(buffer, 0, Length);
}
readStream.Close();
writeStream.Close();
}
}
When I am debugging, after database.CreateTable<ThingObj>(); breakpoint, I am getting that exception and redirected to SQLite.cs class last line.
EDIT : Regarding AkashAmin suggestion I changed sqliteFilename to another string name and solved previous issue. Now I want to create database file in path, but unfortunately Resource.Designer.cs file do not auto generate Raw partial class in Resource.designer.cs . I am getting this error:
'Resource' does not contain a definition for 'Raw'

Thread's response time is very much(not usual)

i want to download a file in C# using a thread in a windows form app,thread works fine at first(for 5 seconds) but suddenly it leaves it work and not respond sometimes for about 10 seconds then it returns a second and then not respond
i am using a class for downloading file
here is the code:
class DownloadFile
{
#region Fields
static Double totalsize;
Double received;
int PartNum;
long start, end;
string savepath;
HttpWebRequest request;
Stream stream;
#endregion
#region Constructors
public DownloadFile() { totalsize = 1; received = 0; }
public DownloadFile(long s, long e, string PATH, HttpWebRequest REQUEST, int Partnumber)
{
totalsize = 1;
PartNum = Partnumber;
received = 0;
start = s;
request = REQUEST;
end = e;
savepath = PATH;
}
#endregion
#region Methods
public void DownLoad()
{
int bytesRead = 0;
byte[] buffer = new byte[1024];
FileStream fstr = new FileStream(savepath + "Part_" + PartNum + Path.GetExtension(Request.RequestUri.ToString()), FileMode.Create, FileAccess.Write);
HttpWebResponse response;
this.request.AddRange(start, end);
response = (HttpWebResponse)this.Request.GetResponse();
stream = response.GetResponseStream();
totalsize = this.end;
bytesRead = stream.Read(buffer, 0, buffer.Length);
while (bytesRead > 0)
{
received += bytesRead;
fstr.Write(buffer, 0, bytesRead);
bytesRead = stream.Read(buffer, 0, buffer.Length);
}
fstr.Close();
stream.Close();
}
public void AppendFiles()
{
}
#endregion
#region properties
public long End
{
get { return end; }
set { end = value; }
}
public long Start
{
get { return start; }
set { start = value; }
}
public Double Received
{
get { return received; }
}
public Double Totalsize
{
get { return totalsize; }
}
public HttpWebRequest Request
{
get { return request; }
set { request = value; }
}
public string SavePath
{
get { return savepath; }
set { savepath = value; }
}
#endregion
}
and here is where thread starts:
Class Program{
List<DownloadFile> DownLoadList = new List<DownloadFile>();
public void DownloadMethod()
{
for (int i = 0; i < DownLoadList.Count; i++)
{
new Thread(new ThreadStart(DownLoadList.ElementAt(i).DownLoad)).Start();
}
}
}
and also i have a timer that updates the download form(progressBar and labels)

Categories

Resources