locked
get file name with FileStream RRS feed

  • Question

  • Hi all,

    I'm doing file transfer with FileStream and this is my code:

     

    Using

     

    client As TcpClient

    = tcpFileListener.EndAcceptTcpClient(ar)

    myStream = client.GetStream()

    clientStreamReader =

    New StreamReader

    (myStream)

     

    Dim RecData(BufferSize - 1) As

    Byte

     

    Dim RecBytes As

    Integer

     

    Dim totalrecbytes As Integer

    = 0

     

    Using Fs As New FileStream("D:\ft\TvPpt.ppt", FileMode.OpenOrCreate, FileAccess

    .Write)

    RecBytes = myStream.Read(RecData, 0, RecData.Length)

     

    While

    RecBytes > 0

    Fs.Write(RecData, 0, RecBytes)

    totalrecbytes += RecBytes

    RecBytes = myStream.Read(RecData, 0, RecData.Length)

     

    End

    While

     

    Dim returndata As String = Encoding

    .ASCII.GetString(RecData)

    Fs.Flush()

    Fs.Close()

     

    End

    Using

     

    End

    Using

    I want to write name of received file instead of TvPpt.ppt. How can i do it?

    Thanks for responses..

    • Moved by Andreas Johansson Friday, July 22, 2011 9:18 AM Due to complaint that C# code was posted in it (From:Visual Basic General)
    Thursday, July 21, 2011 5:18 AM

Answers

  • Andreas, can you show me codes in C#, I'm working on a windows form so may be i can't use WebClient.


    Of course! I made a small sample app that are all in a console app for easy testing of behaviour.

    First I start a TcpListener in its own thread that will wait for connection and then it will first send 4 bytes with the size of the filename, then it will send the filename and last the file contents.

    When I connect the TcpClient to the listener I first get 4 bytes with the size of filename, then get the filename and last I get the rest of the stream into the received filename.

    For testing I assumed the file will be in same directory as executable and no path, only filename.

    using System;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading;
     
    namespace ConsoleApplication1
    {
      class Program
      {
        const int PORT = 5000;
        const string HOSTNAME = "localhost";
        const AddressFamily ADDRESSFAMILY = AddressFamily.InterNetwork;
        const string FILENAME = "Program.cs"; // Must be in same directory as executable
     
        static void Main(string[] args)
        {
          // Start the service
          Thread service = new Thread(new ThreadStart(FileService));
          service.Start();
     
          // Connect to service
          TcpClient client = new TcpClient(ADDRESSFAMILY);
          client.Connect(HOSTNAME, PORT);
     
          // Get the stream and read first 4 bytes, this is the size of the filename
          NetworkStream stream = client.GetStream();
          
          byte[] sizeBuf = new byte[4];
          stream.Read(sizeBuf, 0, 4);
          
          int size = BitConverter.ToInt32(sizeBuf, 0);
          sizeBuf = null;
     
          // Read the filename using the size from previous step
          byte[] filenameBuf = new byte[size];
          stream.Read(filenameBuf, 0, size);
          string filename = UTF8Encoding.UTF8.GetString(filenameBuf);
     
          // Create a stream for new file with unique filename using name received
          FileStream fileStream = File.OpenWrite(String.Format("{1}-{2}-{3} - {0}", filename, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second));
     
          // Copy network stream to new filestream.
          stream.CopyTo(fileStream);
     
          // Done
          fileStream.Close();
          stream.Close();
          client.Close();
        }
     
        static void FileService()
        {
          // Setup service to listen
          IPHostEntry hostEntry = Dns.GetHostEntry(HOSTNAME);
          IPAddress ip = hostEntry.AddressList
            .Where(al => al.AddressFamily == ADDRESSFAMILY)
            .FirstOrDefault();
     
          TcpListener listener = new TcpListener(ip, PORT);
     
          listener.Start();
     
          // Wait for connection
          TcpClient client = listener.AcceptTcpClient();
     
          // Get stream and write 4 bytes with size info of filename
          NetworkStream stream = client.GetStream();
     
          byte[] filenameBuf = UTF8Encoding.UTF8.GetBytes(FILENAME);
          byte[] sizeBuf = BitConverter.GetBytes(filenameBuf.Length); // Always assumed to be 4 bytes
          stream.Write(sizeBuf, 0, 4);
     
          // Write the filename buffer
          stream.Write(filenameBuf, 0, filenameBuf.Length);
     
          // Open source file as stream and copy it directly into network stream.
          FileStream fileStream = File.OpenRead(FILENAME);
          fileStream.CopyTo(stream);
     
          // Done
          fileStream.Close();
          stream.Close();
          client.Close();
        }
      }
    }
    

     Create new C# Console application, paste this in Program.cs, set Program.cs to copy to output directory in project properties.

    WebClient is useful if you download the file from a web server.

    • Marked as answer by goksuuu Monday, July 25, 2011 3:25 PM
    Friday, July 22, 2011 7:14 AM

All replies

  • We cannot see what the location is of the file you get, so show us from where you get that file.

    It is a little bit hidden in what you show us.


    Success
    Cor
    Thursday, July 21, 2011 5:37 AM
  • We cannot see what the location is of the file you get, so show us from where you get that file.

    It is a little bit hidden in what you show us.


    Success
    Cor
    thanks cor for answer, this is server code:

    serverSockStream = tcpClient.GetStream()

    filename=TxtFile.Text

     

    Dim fStream As New FileStream(fileName, FileMode.Open, FileAccess

    .Read)

     

    Dim SendingBuffer(fStream.Length - 1) As

    Byte

    fStream.Read(SendingBuffer, 0, SendingBuffer.Length)

    serverSockStream.Write(SendingBuffer, 0,

    CInt

    (SendingBuffer.Length))

    fStream.Close()

    TxtFile.Text is filename which i selected in server machine

    Thursday, July 21, 2011 8:14 AM
  • There is a few option how to send the filename to the client. You could send the filename over the stream as 0 terminated string, check for this in client and after it has been received continue as usual. Instead of 0 terminated you can use fixed size for block with filename, but be sure that size is enough.

    Another way could be to have a common class/struct that includes the filename and file content as byte array. You serialize this object and then send it, on the other side you deseralize to get same struct with filename and content.

    Just as a tip, have a look at CopyTo method in stream class, it helps you to avoid having buffers when you just want data from one stream to another.

     

    Thursday, July 21, 2011 8:46 AM
  • So you don't get a file, you get a stream.

    Without saying you are doing that, is what you try to do often a subject of malicious code.

    Sometimes the one who offers the stream gives the name of that on the website, but mostly it is hidden.

     

     


    Success
    Cor
    Thursday, July 21, 2011 9:18 AM
  • ok i see then how can i get file with file name, can you show me a cod or an article? 
    Thursday, July 21, 2011 10:39 AM
  • ok i see then how can i get file with file name, can you show me a cod or an article? 

    I have some sample code in C# if you want to see, no time to convert to VB.NET at the moment.
    Thursday, July 21, 2011 11:11 AM
  • If you know the place of the file than that is very simple.

    WebClient.DownloadFile(path,path)

    http://msdn.microsoft.com/en-us/library/ez801hhe.aspx

     


    Success
    Cor
    Thursday, July 21, 2011 2:15 PM
  • I don't think the OP is downloading from web so can't use the webclient but looks like TcpListener and TcpClient and transfering the file over a NetworkStream.
    Thursday, July 21, 2011 2:24 PM
  • Andreas,

    In this business it is not important what you think but what you know.

    I asked the OP what the source was of his stream, he did not give any answer, but asked how to get a file.

    I know that many are searching on internet for a way to get copy protected streams. We are no policemen here, but these forum is also not meant to deliver the base code for that kind of malicious actions.

     


    Success
    Cor
    Thursday, July 21, 2011 6:44 PM
  • Andreas, can you show me codes in C#, I'm working on a windows form so may be i can't use WebClient.

    Friday, July 22, 2011 5:10 AM
  • Andreas, can you show me codes in C#, I'm working on a windows form so may be i can't use WebClient.


    Of course! I made a small sample app that are all in a console app for easy testing of behaviour.

    First I start a TcpListener in its own thread that will wait for connection and then it will first send 4 bytes with the size of the filename, then it will send the filename and last the file contents.

    When I connect the TcpClient to the listener I first get 4 bytes with the size of filename, then get the filename and last I get the rest of the stream into the received filename.

    For testing I assumed the file will be in same directory as executable and no path, only filename.

    using System;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading;
     
    namespace ConsoleApplication1
    {
      class Program
      {
        const int PORT = 5000;
        const string HOSTNAME = "localhost";
        const AddressFamily ADDRESSFAMILY = AddressFamily.InterNetwork;
        const string FILENAME = "Program.cs"; // Must be in same directory as executable
     
        static void Main(string[] args)
        {
          // Start the service
          Thread service = new Thread(new ThreadStart(FileService));
          service.Start();
     
          // Connect to service
          TcpClient client = new TcpClient(ADDRESSFAMILY);
          client.Connect(HOSTNAME, PORT);
     
          // Get the stream and read first 4 bytes, this is the size of the filename
          NetworkStream stream = client.GetStream();
          
          byte[] sizeBuf = new byte[4];
          stream.Read(sizeBuf, 0, 4);
          
          int size = BitConverter.ToInt32(sizeBuf, 0);
          sizeBuf = null;
     
          // Read the filename using the size from previous step
          byte[] filenameBuf = new byte[size];
          stream.Read(filenameBuf, 0, size);
          string filename = UTF8Encoding.UTF8.GetString(filenameBuf);
     
          // Create a stream for new file with unique filename using name received
          FileStream fileStream = File.OpenWrite(String.Format("{1}-{2}-{3} - {0}", filename, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second));
     
          // Copy network stream to new filestream.
          stream.CopyTo(fileStream);
     
          // Done
          fileStream.Close();
          stream.Close();
          client.Close();
        }
     
        static void FileService()
        {
          // Setup service to listen
          IPHostEntry hostEntry = Dns.GetHostEntry(HOSTNAME);
          IPAddress ip = hostEntry.AddressList
            .Where(al => al.AddressFamily == ADDRESSFAMILY)
            .FirstOrDefault();
     
          TcpListener listener = new TcpListener(ip, PORT);
     
          listener.Start();
     
          // Wait for connection
          TcpClient client = listener.AcceptTcpClient();
     
          // Get stream and write 4 bytes with size info of filename
          NetworkStream stream = client.GetStream();
     
          byte[] filenameBuf = UTF8Encoding.UTF8.GetBytes(FILENAME);
          byte[] sizeBuf = BitConverter.GetBytes(filenameBuf.Length); // Always assumed to be 4 bytes
          stream.Write(sizeBuf, 0, 4);
     
          // Write the filename buffer
          stream.Write(filenameBuf, 0, filenameBuf.Length);
     
          // Open source file as stream and copy it directly into network stream.
          FileStream fileStream = File.OpenRead(FILENAME);
          fileStream.CopyTo(stream);
     
          // Done
          fileStream.Close();
          stream.Close();
          client.Close();
        }
      }
    }
    

     Create new C# Console application, paste this in Program.cs, set Program.cs to copy to output directory in project properties.

    WebClient is useful if you download the file from a web server.

    • Marked as answer by goksuuu Monday, July 25, 2011 3:25 PM
    Friday, July 22, 2011 7:14 AM
  • Andreas, can you show me codes in C#, I'm working on a windows form so may be i can't use WebClient.


    Of course! I made a small sample app that are all in a console app for easy testing of behaviour.

     

    Any reason you did not do that in VB, it seems more that you want to abuse this forum with dropping C# code in it which can be used for malicious purposes.

    Moderators, can this thread be removed?

     


    Success
    Cor
    Friday, July 22, 2011 9:18 AM
  • I moved the thread to Network Class Library forum as it was requested due to my offering of C# code in the VB forum

    goksuuu, if you have any issues with the C# code I can help you translate it to VB, you will see the idea of using your own protocol to transfer the filename in the stream together with the content.

    Friday, July 22, 2011 9:21 AM
  • Any reason you did not do that in VB, it seems more that you want to abuse this forum with dropping C# code in it which can be used for malicious purposes.

    Moderators, can this thread be removed?

    I wrote the sample in C# first and haven't had time to rewrite it in VB.NET yet so I offered it as is to the OP and he said yes.

    I do not see any malicious about the code, I am open to discuss it if you like.

    I am a VB general moderator and I moved the thread.

    I dropped you a mail on vb-tips email, if you want to discuss this further with me please reply via mail.

    Friday, July 22, 2011 9:26 AM
  • Thanks Andreas, problem solved
    Monday, July 25, 2011 3:26 PM