Another way to open file

Question

JavierDelgado on Thu, 05 Jul 2012 12:51:49


How can i open a file under C#?

If i open a file by this way:

            Task<StorageFile> tareaarchivo = StorageFile.GetFileFromPathAsync(path).AsTask();
            tareaarchivo.Wait();
            StorageFile archivo = tareaarchivo.Result;
            Task<Stream> tareaarchivoenmemoria = archivo.OpenStreamForReadAsync();
            tareaarchivoenmemoria.Wait();
            Stream flujo = tareaarchivoenmemoria.Result;
            XDocument doc = XDocument.Load(flujo);
            flujo.Flush();
            flujo.Dispose();
            return doc;

i only can open file one time, the second time of the same execution, the app is bloqued in this line:

            tareaarchivoenmemoria.Wait();

Greetings ;). And thanks





Replies

Andrei Marukovich on Thu, 05 Jul 2012 13:45:47


You code can be simplified in the following way:

private async Task<XDocument> SomeFunc(string path)
{
  var archivo = await StorageFile.GetFileFromPathAsync(path);
  var flujo = await archivo.OpenStreamForReadAsync();

  XDocument doc = XDocument.Load(flujo);
  flujo.Flush();
  flujo.Dispose();
  return doc;  
}

Can Bilgin on Thu, 05 Jul 2012 14:27:35


hey javier,

I think the stream you are reading from the file and loading into the xdocument blocks the file so the second time the execution is blocked. You can try cloning the stream and then loading it into the xdocument.

Something like:

var archivo = await StorageFile.GetFileFromPathAsync(path).AsTask();

MemoryStream cloneStream = new MemoryStream();
XDocument doc;

//
// using block to close the stream as soon as we are done with it so the file is not blocked any more.
using (Stream flujo = await archivo.OpenStreamForReadAsync())
{
    // We are cloning the stream here
    await flujo.CopyToAsync(cloneStream);

    // loading the clone of the stream
    doc = XDocument.Load(cloneStream);
}

return doc;

buena suerte :)

JavierDelgado on Thu, 05 Jul 2012 21:39:05


You code can be simplified in the following way:

private async Task<XDocument> SomeFunc(string path)
{
  var archivo = await StorageFile.GetFileFromPathAsync(path);
  var flujo = await archivo.OpenStreamForReadAsync();

  XDocument doc = XDocument.Load(flujo);
  flujo.Flush();
  flujo.Dispose();
  return doc;  
}

Thanks a lot Andrei but i don't like the async void jeje, although I started with all this 2 days ago so it is normal jeje.

Greetings and thanks ;).

 

JavierDelgado on Thu, 05 Jul 2012 21:47:26


hey javier,

I think the stream you are reading from the file and loading into the xdocument blocks the file so the second time the execution is blocked. You can try cloning the stream and then loading it into the xdocument.

Something like:

var archivo = await StorageFile.GetFileFromPathAsync(path).AsTask();

MemoryStream cloneStream = new MemoryStream();
XDocument doc;

//
// using block to close the stream as soon as we are done with it so the file is not blocked any more.
using (Stream flujo = await archivo.OpenStreamForReadAsync())
{
    // We are cloning the stream here
    await flujo.CopyToAsync(cloneStream);

    // loading the clone of the stream
    doc = XDocument.Load(cloneStream);
}

return doc;

buena suerte :)


Can Bilgin
Blog CompuSight

Also thanks a lot, but XDocument don't load the MemoryStream, so my "trick" is:

        public static XDocument CargarXDocument(string path)
        {
            StorageFile archivo = StorageFile.GetFileFromPathAsync(path).AsTask().Result;
            Task<string> tareastring = Windows.Storage.FileIO.ReadTextAsync(archivo).AsTask();
            XDocument doc = XDocument.Parse(tareastring.Result);
            return doc;
        }

Thanks so much Can and greetings ;).