how to split a wmv file - c#

im doing a application in which i split a wmv file and transfer it to otherlocation(in 'x' kbs) .after the transfer gets completed the file doesnt play,it gives a message as the format is not supported.is there anyother way to do it.
sory i will explain what im doing now
i wrote an remote application,i want to transfer a .wmv file from one machine to other,i want to split the .wmv and send it to the remote machine and use it there.if i try to send the complete file means it will take lot of memory that seems very bad.so i want to split it and send it.but the file doesnt gets played it raises an exception the format is not supported.
the following is the code im doing i just done it in the local machine itself(not remoting):
try
{
FileStream fswrite = new FileStream("D:\\Movie.wmv", FileMode.Create);
int pointer = 1;
int bufferlength = 12488;
int RemainingLen = 0;
int AppLen = 0;
FileStream fst = new FileStream("E:\\Movie.wmv", FileMode.Open);
int TotalLen = (int)fst.Length;
fst.Close();
while (pointer != 0)
{
byte[] svid = new byte[bufferlength];
using (FileStream fst1 = new FileStream("E:\\Movie.wmv", FileMode.Open))
{
pointer = fst1.Read(svid, AppLen, bufferlength);
fst1.Close();
}
fswrite.Write(svid, 0, pointer);
AppLen += bufferlength;
RemainingLen = TotalLen-AppLen;
if(RemainingLen < bufferlength)
{
byte[] svid1 = new byte[RemainingLen];
using (FileStream fst2 = new FileStream("E:\\Movie.wmv", FileMode.Open))
{
pointer = fst2.Read(svid1, 0, RemainingLen);
fst2.Close();
}
fswrite.Write(svid, 0, pointer);
break;
}
}
fswrite.Close();
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}

You'll probably find Good way to send a large file over a network in C# helpful.

Im going to make the assumtion your spliting the file when your sending it, and not trying to have the wmv in 3 different files on the remote machine.
When your sending the file what you basicly do is this:
Local machine
1) Read 16k bytes ( Or whatever number you prefere )
2) Send those 16k bytes over the network
3) Repeat above steps untill done
Remote machine
1) Listen for a connection
2) Get 16k bytes
3) Write 16k bytes
4) Repeat untill done.
This method will work, but your kind of inventing the wheel again, i would recommend using either something as simple as File.Copy ( Works fine over the network ) or if that does not meet your needs perhaps using a FTP client / server solution ( Plenty of C# examples on the net that can be hosted inside your application ).

i tried this
private void Splitinthread()
{
int bufferlength = 2048;
int pointer = 1;
int offset = 0;
int length = 0;
byte[] buff = new byte[2048];
FileStream fstwrite = new FileStream("D:\\TEST.wmv", FileMode.Create);
FileStream fst2 = new FileStream("E:\\karthi.wmv", FileMode.Open);
int Tot_Len = (int)fst2.Length;
int Remain_Buff = 0;
//Stream fst = File.OpenRead("E:\\karth.wmv");
while (pointer != 0)
{
try
{
fst2.Read(buff, 0, bufferlength);
fstwrite.Write(buff, 0, bufferlength);
offset += bufferlength;
Remain_Buff = Tot_Len - offset;
Fileprogress.Value = CalculateProgress(offset, Tot_Len);
if (Remain_Buff < bufferlength)
{
byte[] buff1 = new byte[Remain_Buff];
pointer = fst2.Read(buff1, 0, Remain_Buff);
fstwrite.Write(buff1, 0, pointer);
Fileprogress.Value = CalculateProgress(offset, Tot_Len);
fstwrite.Close();
fst2.Close();
break;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
MessageBox.Show("Completed");
}

Related

c# read and delete file used for messaging

I am writing a payments system which communicates with a very old POS interface through files.
The POS system tries to open/create a file (fixed to a single name). If it opens the file it then writes the payment request and closes the file, if it fails to open the file the POS system will wait and try again (sorry don't know how long between attempts, but very short).
I have to monitor the directory and when I see a new file arrive, then I have to try to open the file and block any access to the POS system from writing any new entries. While I have the file open I read through the records and send them to the payments system, once I receive confirmation I have to close the file and delete it.
My concern/problem is - how do I block the POS system from writing anything between the close and delete statements?
I can set the FileShare to Delete, which allows my program to delete the file before I close it, but this means other processes could also delete the file regardless of whether or not I processed the records successfully.
Option 1
void Main()
{
string filename = #"C:\Temp\CHARGES.TXT";
using (var fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.None))
{
var buffer = new byte[1024];
while (true)
{
var bytesRead = fs.Read(buffer, 0, buffer.Length);
if (bytesRead == 0)
break;
var text = ASCIIEncoding.ASCII.GetString(buffer, 0, bytesRead);
Console.Write(text);
}
}
File.Delete(filename);
}
Option 2
void Main()
{
string filename = #"C:\Temp\CHARGES.TXT";
using (var fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Delete))
{
var buffer = new byte[1024];
while (true)
{
var bytesRead = fs.Read(buffer, 0, buffer.Length);
if (bytesRead == 0)
break;
var text = ASCIIEncoding.ASCII.GetString(buffer, 0, bytesRead);
Console.Write(text);
}
File.Delete(filename);
}
}
As this is a payments system any loss of records is not acceptable. Also as I have no control over the POS system I cannot change the way it works.
Thank you in advance
Thank you to #Lasse and #Sam for your helpful comments. I have made the following changes to the code:
void Main()
{
string filename = #"C:\Temp\CHARGES.TXT";
int start = 0;
int end = 0;
using (var fs = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.Read))
{
// get a big enough buffer to hold the whole file and read it in
long fileSize = new FileInfo(filename).Length;
var buffer = new byte[fileSize];
var bytesRead = fs.Read(buffer, 0, buffer.Length);
try
{
// convert each line to ASCII to process through to API
while (end < bytesRead)
{
while (end < bytesRead && buffer[end] != 0x0A && buffer[end] != 0x0D)
{
end++;
}
var text = ASCIIEncoding.ASCII.GetString(buffer, start, end - start);
// Send to API
Console.WriteLine("Start [{0}] End [{1}] Text [{2}]", start, end, text);
if (end < bytesRead)
{
end += 2;
start = end;
}
if (end > bytesRead / 2)
{
throw new NotImplementedException();
}
}
}
catch (Exception e)
{
Console.WriteLine("just to prove the partial");
}
finally
{
// convert any remaining records back to bytes and write back to file
fs.SetLength(0);
fs.Write(buffer, end, bytesRead - end);
}
}
}
The process will now go through the file and write back any failed/unprocessed messages to the file at the end - this covers off my locking concerns as well as covering the individual record failures.
Thank you agin

C# Cyclic redundancy check Exception when reading the stream of a CD

I want to read a CD to write it's content to a file, but I get an IOException (Data error Cyclic Redundancy Check) after a few read/write to my output file.
I'm trying to make an ISO creator program and the disk I read is 500 Mo game CD, and the exception arise after reading about at 1,9 Mo of data. The CD is not broken and perfectly usable.
I don't know if they are limitations with chunk size or buffer size (using 4096 bytes).
I'm very interested by any idea or experience to fix that problem.
EDIT
I get this error with every CD, not only this one. And it's not broken, as I used it just before starting to make the program to install the game it contains.
I use this code to read the CD :
const int BUFFER_SIZE = 4096;
private void MakeISO()
{
_HDEV = NativeMethods.CreateFileR(DRIVE_NAME);
string targetFile = TARGET + "\\" + NAME;
try
{
_FSR = new FileStream(_HDEV, FileAccess.Read, BUFFER_SIZE);
_FSW = new FileStream(targetFile, FileMode.Create, FileAccess.Write, FileShare.None, BUFFER_SIZE);
byte[] buffer = new byte[BUFFER_SIZE];
int length;
while ((length = _FSR.Read(buffer, 0, buffer.Length)) > 0)
{
_FSW.Write(buffer, 0, buffer.Length);
}
// Don't work either
//do
//{
// _FSR.Read(buffer, 0, BUFFER_SIZE);
// _FSW.Write(buffer, 0, BUFFER_SIZE);
//}
//while (_fsw.Position == _fsr.Position);
}
catch (Exception ex)
{
//
}
finally
{
CloseAll();
}
}

Moving compressed file from one computer to another

My project is FTP, and I need some help.
1. I'm using Huffman Code to compress file and then send it to the computer that is asking the file.
The function from the huffman code returns byte array.
I don't understand how to send the bytes.
I have this function:
private void UpLoad(string namefile)
{
try
{
FileInfo ftemp = new FileInfo(ClientForm.SharedFolderPath + "\\" + namefile); // file name
long total = ftemp.Length; // size of file in long
long rdby = 0;
int len = 0; // the numbers of bytes to read
byte[] buffed = new byte[1024];
//Open the file requested for download
FileStream fin = new FileStream(ClientForm.SharedFolderPath + "\\" + namefile, FileMode.Open, FileAccess.Read);
//One way of transfer over sockets is Using a NetworkStream
//It provides some useful ways to transfer data
NetworkStream nfs = client.GetStream();
//lock the Thread here
lock (this)
{
while (rdby < total && nfs.CanWrite)
{
//Read from the File (len contains the number of bytes read)
len = fin.Read(buffed, 0, buffed.Length);
//wait for downloader..
Thread.Sleep(1);
//Write the Bytes on the Socket
nfs.Write(buffed, 0, len);
//Increase the bytes Read counter
rdby = rdby + len;
}
//Display a Message Showing Sucessful File Transfer
fin.Close();
}
}
catch (Exception ed)
{
MessageBox.Show(ed.Message);
}
}
Can someone help me please?
I need to identify when the file is compressed and if its not, I need to compress it.
What is the best way to do that?

C# sockets: can't read after writing to socket

In my client/server application my client wiil communicate with the server for 2 functions: the client will either request data from the server or it will send data so the server will save it. I'm using one socket for both methods, and the method to be used is defined by the first byte sent. If the first byte is "1" it is requesting data. If it is "2", it will send data (data bytes are sent after the "2" byte). It works perfectly for sending data. But when I'm requesting data it works, as long as I don't read the socket stream in the client. It's like if I make the client read data after sending data, the server will have no data to read, and it just crashes when trying to read the data.
Here is my server code:
private const int BufferSize = 1024;
NetworkStream netstream = null;
byte[] RecData = new byte[BufferSize];
int RecBytes;
try {
netstream = clientSocket.GetStream();
int totalrecbytes = 0;
using (MemoryStream ms = new MemoryStream()) {
//When I get here, there is no data to read
while ((RecBytes = netstream.Read(RecData, 0, RecData.Length)) > 0) {
ms.Write(RecData, 0, RecBytes);
totalrecbytes += RecBytes;
}
byte[] bytes = ms.ToArray();
byte b = bytes[0];
switch (b) {
case 1:
//Here I gather data and put it in "stream" variable
byte[] SendingBuffer = null;
int NoOfPackets = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(stream.Length) / Convert.ToDouble(BufferSize)));
int TotalLength = (int)stream.Length, CurrentPacketLength, counter = 0;
for (int i = 0; i < NoOfPackets; i++) {
if (TotalLength > BufferSize) {
CurrentPacketLength = BufferSize;
TotalLength = TotalLength - CurrentPacketLength;
}
else
CurrentPacketLength = TotalLength;
SendingBuffer = new byte[CurrentPacketLength];
stream.Read(SendingBuffer, 0, CurrentPacketLength);
netstream.Write(SendingBuffer, 0, (int)SendingBuffer.Length);
}
netstream.Flush();
}
catch (Exception e) {
Console.WriteLine("EXCEPTION:\n" + e.ToString());
}
break;
case 2:
//Code to read data
break;
}
}
netstream.Close()
clientSocket.Close();
And here is my client code:
using (System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient()) {
string returnData = "";
IAsyncResult ar = clientSocket.BeginConnect("127.0.0.1", 8080, null, null);
System.Threading.WaitHandle wh = ar.AsyncWaitHandle;
try {
if (!ar.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(5), false)) {
clientSocket.Close();
Console.WriteLine("Timeout");
return;
}
System.Net.Sockets.NetworkStream serverStream = clientSocket.GetStream();
byte b = 1;
byte[] outStream = { b };
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
//If I comment following lines, the server can read sent data, but server can't otherwise
byte[] RecData = new byte[1024];
int RecBytes;
int totalrecbytes = 0;
MemoryStream MS = new MemoryStream();
while ((RecBytes = serverStream.Read(RecData, 0, RecData.Length)) > 0) {
MS.Write(RecData, 0, RecBytes);
totalrecbytes += RecBytes;
}
serverStream.Close();
clientSocket.Close();
clientSocket.EndConnect(ar);
}
catch (Exception ex) {
Console.WriteLine("Exceção: " + ex.ToString());
}
finally {
wh.Close();
}
}
So, how can I send data to server and read the response? (I tried even putting the thread to sleep after sending data, with no luck.)
Thanks in advance.
EDIT:
With some debug messages I discovered that the server do read the "1" byte that was sent, but somehow it gets stuck inside the while loop, like, the server just stops there, no more loops and it does not leave the while loop. I saw that after writing "loop" in console inside the while loop, and writing read bytes also in console. It wrote "loop" once, and the read byte.
This code worries me:
//When I get here, there is no data to read
while ((RecBytes = netstream.Read(RecData, 0, RecData.Length)) > 0) {
ms.Write(RecData, 0, RecBytes);
totalrecbytes += RecBytes;
}
You are reading until the client closes the connection (or shuts down sending, which you don't do). But the client only closes when the server has replied. The server reply will never come. It is a deadlock.
Solution: Read a single byte to determine the requests command (b).
Unrelated to the question, your "packetised" sending (NoOfPackets, ...) does not seem to serve any purpose. Just use Stream.Copy to write. TCP does not have packets.
An even better solution would be to abandon your custom TCP protocol and use an HTTP library. All these concerns just go away. There are various smaller problems with your code that are very typical to see in TCP code.

TcpListener truncating byte array randomly

I am writing what is essentially an image backup server to store images. It is a one way service that will not return anything beyond a basic success or failure message to the client.
The issue that I am experienceing is that when I send a byte array through the network stream, it is being cut-off before the end of the stream at random locations. I do not have this issue when I run the server on my development machine and connect locally, but rather it only occurs when the server is deployed on a remote server.
When I send very small arrays ( < 512 bytes) the server recieves the entire stream successfully, but on streams larger than 2000 bytes I experience issues. The code for the client is as follows:
try
{
TcpClient Voice = new System.Net.Sockets.TcpClient();
//Obviously I use the remote IP when it is deployed - but have altered it for privacy.
IPEndPoint BackupServer = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 57000);
Voice.Connect(BackupServer);
NetworkStream DataStream = Voice.GetStream();
byte[] buffer = new ASCIIEncoding().GetBytes(ImageData.GetXml());
DataStream.Write(buffer, 0, buffer.Length);
DataStream.Flush();
}
catch
{
}
try
{
buffer = new byte[4096];
int read = DataStream.Read(buffer, 0, buffer.Length);
MessageBox.Show(new ASCIIEncoding().GetString(buffer) + " : " + read.ToString());
}
catch
{
}
The client code executes without any errors or problems regardless of the size of data I send.
And the code for the server side is as follows:
private void BackMeUp(object voice)
{
TcpClient Voice = (TcpClient)voice;
Voice.ReceiveTimeout = 30000;
NetworkStream DataStream = Voice.GetStream();
try
{
bool ShouldLoop = true;
//int loops = 0;
int loops = -1;
byte[] input = new byte[2048];
byte[] buffer = new byte[0];
//while (ShouldLoop)
while(loops != 0)
{
loops = DataStream.Read(input, 0, 2048);
for (int x = 0; x < loops; x++)
{
Array.Resize(ref buffer, buffer.Length + 1);
buffer[buffer.Length - 1] = input[x];
}
//if (loops < 2048)
//{
//ShouldLoop = false;
//break;
//}
}
while (true)
{
StringReader Reader = new StringReader(new ASCIIEncoding().GetString(buffer, 0, buffer.Length));
DataSet DS = new DataSet();
DS.ReadXml(Reader);
if (DS.Tables.Count > 0)
{
if (DS.Tables["Images"].Rows.Count > 0)
{
foreach (DataRow row in DS.Tables["Images"].Rows)
{
//
}
}
}
string response = "Got it!";
DataStream.Write(new ASCIIEncoding().GetBytes(response), 0, response.Length);
DataStream.Flush();
Voice.Close();
break;
}
}
catch (Exception Ex)
{
File.WriteAllText("Elog.txt", Ex.Message + " " + (Ex.InnerException != null ? Ex.InnerException.ToString() : " no Inner"));
Voice.Close();
}
}
The server recieves the data fine, and closes the stream when it reaches the end, however the data is cut-off and I get an error when I try to rebuild the dataset.
I have the impression this has to do with the time it takes to send the stream, and I have played around with the Close and Flush commands but I feel like I'm just shooting in the dark. Any help would be appreciated.
Concise version of question: What factors are involved with a TcpListener that could cause a) the truncation of the stream. or b) premature closing of the stream prior to all bytes being read. When the listener in question is on a remote host rather than a local server.
The Read method doesn't have to return the number of bytes that you requested, or the entire stream at once. Especially if the stream is slow, it will be returned in small chunks.
Call the Read method repeatedly, and handle the data for each block that you get. The Read method returns zero when the stream is read to the end:
buffer = new byte[4096];
do {
int read = DataStream.Read(buffer, 0, buffer.Length);
if (read != 0) {
// handle the first "read" bytes of the buffer (index 0 to read-1)
}
} while (read != 0);
If you know that your buffer is enough for any stream, you can fill up the buffer and handle it afterwards:
buffer = new byte[4096];
int offset = 0;
do {
int read = DataStream.Read(buffer, offset, buffer.Length - offset);
offset += read;
} while (read != 0);
// handle the first "offset" bytes of the buffer (index 0 to offset-1)

Categories