I am converting 3D objects to one xml file, write it to hard drive, then read it from hard drive and upload to Mysql database as a blob. Then I delete created xml.file from my hard drive. Is it somehow possible to do this (create xml file/upload to database) so that I don't have to write it to drive at first, then read it, then delete it? If I could somehow create xml file and pass it directly without the need to save it on drive. Any ideas?
Here I write xml file to drive (EDITED):
public Stream WriteXml(List<object> gridEntities, string fileName)
{
XDocument doc = new XDocument();
XElement root = new XElement("ViewportLayout");
XElement xEntities = new XElement("Entities");
xEntities.Add(...);
root.Add(xEntities);
doc.Add(root);
//var path = string.Format("C:\\Users\\NP\\Desktop\\Saves\\{0}", fileName);
//doc.Save(path);
Stream stream = new MemoryStream(); // Create a stream
doc.Save(stream); // Save XDocument into the stream
stream.Position = 0; // Rewind the stream ready to read from it elsewhere
return stream;
}
Here I upload it to data base:
public static void SaveGridXmlFileToDataBase(Stream stream, string projectName, string filePath, string gridName, string gridGuid)
{
if (OpenConnection() == true)
{
byte[] file;
using (stream)
{
using (var reader = new BinaryReader(stream))
{
file = reader.ReadBytes((int)stream.Length);
}
}
string project = string.Concat(projectName, "_grids");
string query = String.Format("INSERT INTO {0} SET name=#name, guid=#guid, xml=#File;", project);
using (var sqlWrite = new MySqlCommand(query, connection))
{
sqlWrite.Parameters.Add("#name", MySqlDbType.VarChar).Value = gridName;
sqlWrite.Parameters.Add("#guid", MySqlDbType.VarChar).Value = gridGuid;
sqlWrite.Parameters.Add("#File", MySqlDbType.LongBlob).Value = file;
sqlWrite.ExecuteNonQuery();
}
CloseConnection();
}
}
Related
I'm creating and downloading a .zip folder with images inside, but the images are damaged or corrupted and I don´t know how to fix it.
try{
byte[] retVal = null;
query = "Select query";
OrderList = BringDeliveryImageDirectories(query);
using (var memoryStream = new MemoryStream())
{
using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
{
foreach (var list in orderList)
{
ImageName = list.getImgFrontDni_tr().Split("/");
var file1 = archive.CreateEntry(imageName[5]);
using(BinaryWriter streamWriter = new BinaryWriter(file1.Open()))
{
streamWriter.Write(System.IO.File.ReadAllBytes("wwwroot" + list.getImgFrenteDni_tr()),0,("wwwroot" + list.getImgFrenteDni_tr()).Length);
streamWriter.Close();
}
ImageName = list.getImgDniDni_tr().Split("/");
var file2 = archive.CreateEntry(imageName[5]);
using(BinaryWriter streamWriter = new BinaryWriter(file2.Open()))
{
streamWriter.Write(System.IO.File.ReadAllBytes("wwwroot" + list.getImgDorsoDni_tr()),0, ("wwwroot" + list.getImgDorsoDni_tr()).Length);
streamWriter.Close();
}
}
memoryStream.Position = 0;
}
retVal = memoryStream.ToArray(); //
//return File(memoryStream, "application/zip", "Images.zip");
}
}
return File(retVal, MediaTypeNames.Application.Zip, "Images.zip");
}
I tried changing the BinaryWriter with StreamWriter, the Return File(), streamWriter.Write parameters, but nothing is fixing my problem, I searched here in Stack forum but didn't work for me.
The .zip folder is downloading and bringing all the images okey, but when I try to open an image, it says:
The image can´t open because format not compatible or damage
or also I have a popup again trying to open an image
Error to compress the folder. Windows cannot complete the extraction. Failed to create destiny file
I am working on a feature that can take xmlstring as an input and uploads it to the server. Below is the code I'm playing around but I saw some answers in the other places suggesting System.io.stream. So, I'm curious about that way of doing it. How can I just store the .xml on the server with/without saving it on the disk.
Code for using file on the Base Directory folder location
string filename = "Sample.XML";
List<string> file = new();
file.Add(filename);
//Downloading XML string using web client
string Xml = _webClientService.DownloadXml("http://aws.api/Links?=admin");
string fileLocation = AppDomain.CurrentDomain.BaseDirectory + "\\SampleFiles";
if (!Directory.Exists(fileLocation)) { Directory.CreateDirectory(fileLocation); }
XmlReader reader = XmlReader.Create(Xml);
XDocument doc = XDocument.Load(reader);
doc.Save(fileLocation + $"\\{file}");
I'm yet to work on the upload piece. But the method declaration would look like:
UploadFiles(string filelocation, List<string> fileNames);
2nd method using System.io.stream
Stream s = _httpService.GetStream("http://aws.api/Links?=admin");
var file = "sample.gz";
Stream gZip = new GZipStream(s, CompressionMode.Decompress);
XmlReader reader = XmlReader.Create(gZip, new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment });
reader.MoveToContent();
XDocument doc = XDocument.Load(reader);
And for this one, the prototype can be like:
UploadFileStream(string file, Stream strm);
Code for GetStream:
public static async Task<Stream> GetStream(string url)
{
var t = Task.Run(() => httpClient.GetAsync(url));
t.Wait();
HttpResponseMessage response = t.Result;
Stream res;
// Handle the response
switch (response.StatusCode)
{
case HttpStatusCode.OK:
res = await response.Content.ReadAsStreamAsync();
break;
default:
int statusCode = (int)response.StatusCode;
throw new HttpException(statusCode, response.ReasonPhrase);
}
return res;
}
Is it possible to avoid gZip conversion & store xmlfile direct to server using the memory stream?
I have some files inside in one .tar.gz archive. These files are on a linux server.How can I read from a specific file inside this archive if I know it's name?
For reading direct from the txt file, I used the following code:
Uri urlFile = new Uri("ftp://" + ServerName + "/%2f" + FilePath + "/" + fileName);
WebClient req = new WebClient() { Credentials=new NetworkCredential("user","psw")};
string result = req.DownloadString(urlFile);
It's possible to read this file without copying the archive on the local machine, something like the code above?
I found a solution. Maybe this can help you guys.
// archivePath="ftp://myLinuxServer.com/%2f/move/files/archive/20170225.tar.gz";
public static string ExtractFileFromArchive(string archivePath, string fileName)
{
string stringFromFile="File not found";
WebClient wc = new WebClient() { Credentials = cred, Proxy= webProxy }; //Create webClient with all necessary settings
using (Stream source = new GZipInputStream(wc.OpenRead(archivePath))) //wc.OpenRead() create one stream with archive tar.gz from our server
{
using (TarInputStream tarStr =new TarInputStream(source)) //TarInputStream is a stream from ICSharpCode.SharpZipLib.Tar library(need install SharpZipLib in nutgets)
{
TarEntry te;
while ((te = tarStr.GetNextEntry())!=null) // Go through all files from archive
{
if (te.Name == fileName)
{
using (Stream fs = new MemoryStream()) //Create a empty stream that we will be fill with file contents.
{
tarStr.CopyEntryContents(fs);
fs.Position = 0; //Move stream position to 0, in order to read from beginning
stringFromFile = new StreamReader(fs).ReadToEnd(); //Convert stream to string
}
break;
}
}
}
}
return stringFromFile;
}
I am using SSH.NET library to download files. I want to save the downloaded file as a file in memory, rather than a file on disk but it is not happening.
This is my code which works fine:
using (var sftp = new SftpClient(sFTPServer, sFTPPassword, sFTPPassword))
{
sftp.Connect();
sftp.DownloadFile("AFile.txt", System.IO.File.Create("AFile.txt"));
sftp.Disconnect();
}
and this is the code which doesn't work fine as it gives 0 bytes stream.
using (var sftp = new SftpClient(sFTPServer, sFTPPassword, sFTPPassword))
{
sftp.Connect();
System.IO.MemoryStream mem = new System.IO.MemoryStream();
System.IO.TextReader textReader = new System.IO.StreamReader(mem);
sftp.DownloadFile("file.txt", mem);
System.IO.TextReader textReader = new System.IO.StreamReader(mem);
string s = textReader.ReadToEnd(); // it is empty
sftp.Disconnect();
}
You can try the following code, which opens the file on the server and reads it back into a stream:
using (var sftp = new SftpClient(sFTPServer, sFTPUsername, sFTPPassword))
{
sftp.Connect();
// Load remote file into a stream
using (var remoteFileStream = sftp.OpenRead("file.txt"))
{
var textReader = new System.IO.StreamReader(remoteFileStream);
string s = textReader.ReadToEnd();
}
}
For simple text files, it's even easier:
var contents = sftp.ReadAllText(fileSpec);
I had a similar issue with the ScpClient, I needed to reset the stream position to the beginning after downloading the file.
using (var sftp = new SftpClient(sFTPServer, sFTPPassword, sFTPPassword))
{
sftp.Connect();
System.IO.MemoryStream mem = new System.IO.MemoryStream();
System.IO.TextReader textReader = new System.IO.StreamReader(mem);
sftp.DownloadFile("file.txt", mem);
// Reset stream to the beginning
mem.Seek(0, SeekOrigin.Begin);
System.IO.TextReader textReader = new System.IO.StreamReader(mem);
string s = textReader.ReadToEnd();
sftp.Disconnect();
}
I am required to read the contents of an .xml file using the Stream (Here the xml file is existing with in the zip package). Here in the below code, I need to get the file path at runtime (here I have hardcoded the path for reference). Please let me know how to read the file path at run time.
I have tried to use string s =entry.FullName.ToString(); but get the error "Could not find the Path". I have also tried to hard code the path as shown below. however get the same FileNotFound error.
string metaDataContents;
using (var zipStream = new FileStream(#"C:\OB10LinuxShare\TEST1\Temp" + "\\"+zipFileName+".zip", FileMode.Open))
using (var archive = new ZipArchive(zipStream, ZipArchiveMode.Read))
{
foreach (var entry in archive.Entries)
{
if (entry.Name.EndsWith(".xml"))
{
FileInfo metadataFileInfo = new FileInfo(entry.Name);
string metadataFileName = metadataFileInfo.Name.Replace(metadataFileInfo.Extension, String.Empty);
if (String.Compare(zipFileName, metadataFileName, true) == 0)
{
using (var stream = entry.Open())
using (var reader = new StreamReader(stream))
{
metaDataContents = reader.ReadToEnd();
clientProcessLogWriter.WriteToLog(LogWriter.LogLevel.DEBUG, "metaDataContents : " + metaDataContents);
}
}
}
}
}
I have also tried to get the contents of the .xml file using the Stream object as shown below. But here I get the error "Stream was not readable".
Stream metaDataStream = null;
string metaDataContent = string.Empty;
using (Stream stream = entry.Open())
{
metaDataStream = stream;
}
using (var reader = new StreamReader(metaDataStream))
{
metaDataContent = reader.ReadToEnd();
}
Kindly suggest, how to read the contents of the xml with in a zip file using Stream and StreamReader by specifying the file path at run time
Your section code snippet is failing because when you reach the end of the first using statement:
using (Stream stream = entry.Open())
{
metaDataStream = stream;
}
... the stream will be disposed. That's the point of a using statment. You should be fine with this sort of code, but load the XML file while the stream is open:
XDocument doc;
using (Stream stream = entry.Open())
{
doc = XDocument.Load(stream);
}
That's to load it as XML... if you really just want the text, you could use:
string text;
using (Stream stream = entry.Open())
{
using (StreamReader reader = new StreamReader(stream))
{
text = reader.ReadToEnd();
}
}
Again, note how this is reading before it hits the end of either using statement.
Here is a sample of how to read a zip file using .net 4.5
private void readZipFile(String filePath)
{
String fileContents = "";
try
{
if (System.IO.File.Exists(filePath))
{
System.IO.Compression.ZipArchive apcZipFile = System.IO.Compression.ZipFile.Open(filePath, System.IO.Compression.ZipArchiveMode.Read);
foreach (System.IO.Compression.ZipArchiveEntry entry in apcZipFile.Entries)
{
if (entry.Name.ToUpper().EndsWith(".XML"))
{
System.IO.Compression.ZipArchiveEntry zipEntry = apcZipFile.GetEntry(entry.Name);
using (System.IO.StreamReader sr = new System.IO.StreamReader(zipEntry.Open()))
{
//read the contents into a string
fileContents = sr.ReadToEnd();
}
}
}
}
}
catch (Exception)
{
throw;
}
}