Merging files with different extensions into another file bytes - c#

I'm trying to figure out how to attach a few files whose paths can be found at a ListBox into another file bytes. The files can have different extensions. For example one may be text document, one picture and one executable. So, when you open the main file, they all should execute in same time with the main file. I have a Server/Client project where I send the main file bytes to the server and he does his job.
byte[] mainFileBytes = File.ReadAllBytes(MainFilePath);
int mainFileLength = mainFileBytes.Length;
byte[] mainFileLengthBuffer = BitConverter.GetBytes(mainFileLength);
Globals.GlobalBuffer = Methods.CombineBytes(mainFileLengthBuffer, mainFileBytes);
client.GetStream().Write(Globals.GlobalBuffer, 0, Globals.GlobalBuffer.Length);
This is how I send the main file to the server. Somehow, I have to attach those files to the main file.
Edit: Thinking of sending each of those files to the server, but the problem is that I don't know how to distinguish them.
Send code:
var requestBytes = new byte[26];
var requestByteCount = client.GetStream().Read(requestBytes, 0, requestBytes.Length);
if (Encoding.Unicode.GetString(requestBytes, 0, requestByteCount).Contains("ATTACHEDFILES"))
{
if (chMFBListBox.Items.Count > 0)
{
foreach (string file in chMFBListBox.Items)
{
var fileBytes = File.ReadAllBytes(file);
var fileLength = fileBytes.Length;
var fileLengthBuffer = BitConverter.GetBytes(fileLength);
Globals.GlobalBuffer = Methods.CombineBytes(fileLengthBuffer, fileBytes);
client.GetStream().Write(Globals.GlobalBuffer, 0, Globals.GlobalBuffer.Length);
}
}
else
{
// Notifying the server there aren't attached files
Globals.GlobalBuffer = Encoding.Unicode.GetBytes("NO");
client.GetStream().Write(Globals.GlobalBuffer, 0, Globals.GlobalBuffer.Length);
}
}

Related

How can I save a stream of Json data to a text file in C# Windows Forms app?

I've got a stream of data incoming as a Json file and I'm trying to save it to a text file, I've got it working here below however, when i check the file, it only has the last Json message received saved, I am trying to get it so that once it saves a line it goes onto a new line and prints the latest Json message below. at the moment it will print let's say 1000 lines but they are all the same and they match the latest Json received.
Any help would be much appreciated.
void ReceiveData() //This function is used to listen for messages from the flight simulator
{
while (true)
{
NetworkStream stream = client.GetStream(); //sets the network stream to the client's stream
byte[] buffer = new byte[256]; //Defines the max amount of bytes that can be sent
int bytesRead = stream.Read(buffer, 0, buffer.Length);
if (bytesRead > 0)
{
string jsonreceived = Encoding.ASCII.GetString(buffer, 0, bytesRead); //Converts the received data into ASCII for the json variable
JavaScriptSerializer serializer = new JavaScriptSerializer();
TelemetryUpdate telemetry = serializer.Deserialize<TelemetryUpdate>(jsonreceived);
this.Invoke(new Action(() => { TelemetryReceivedLabel.Text = jsonreceived;
})) ;
Updatelabels(telemetry); //runs the update labels function with the telemetry data as an argument
File.Delete(#"c:\temp\BLACKBOX.txt"); // this deletes the original file
string path = #"c:\temp\BLACKBOX.txt"; //this stores the path of the file in a string
using (StreamWriter sw = File.CreateText(path)) // Create a file to write to.
{
for (int i = 0; i<10000; i++)
{
sw.Write(jsonreceived.ToString()); //writes the json data to the file
}
}
}
}
}
As per the .NET documentation for File.CreateText:
Creates or opens a file for writing UTF-8 encoded text. If the file already exists, its contents are overwritten.
So, every time you call File.CreateText you're creating a new StreamWriter that's going to overwrite the contents of your file. Try using File.AppendText instead to pick up where you left off.

Uploading media files to Azure File Share over 4 MB corrupts them

I'm trying to upload large files to Azure File Share via the Azure.Storage.Files.Shares library and am I running into corruption issues on all media files (images, PDFs, etc) over ~4 MB. Azure File Share has a limit of 4 MB for a single request which is why I've split the upload in to multiple chunks, but it still corrupts the files despite every chunk upload returning a 201.
Notes:
It doesn't seem like it's an issue with having to write multiple chunks as I can write a 3 MB file in as many chunks as I want and it will be totally fine
.txt files over 4 MB have no issues and display totally fine after uploading
This uploading portion of this function is basically copied/pasted from the only other stack overflow "solution" I found regarding this issue:
public async Task WriteFileFromStream(string fullPath, MemoryStream stream)
{
// Get pieces of path
string dirName = Path.GetDirectoryName(fullPath);
string fileName = Path.GetFileName(fullPath);
ShareClient share = new ShareClient(this.ConnectionString, this.ShareName);
// Set position of the stream to 0 so that we write all contents
stream.Position = 0;
try
{
// Get a directory client for specified directory and create the directory if it doesn't exist
ShareDirectoryClient directory = share.GetDirectoryClient(dirName);
directory.CreateIfNotExists();
if (directory.Exists())
{
// Get file client
ShareFileClient file = directory.GetFileClient(fileName);
// Create file based on stream length
file.Create(stream.Length);
int blockSize = 300 * 1024; // can be anything as long as it doesn't exceed 4194304
long offset = 0; // Define http range offset
BinaryReader reader = new BinaryReader(stream);
while (true)
{
byte[] buffer = reader.ReadBytes(blockSize);
if (buffer.Length == 0)
break;
MemoryStream uploadChunk = new MemoryStream();
uploadChunk.Write(buffer, 0, buffer.Length);
uploadChunk.Position = 0;
HttpRange httpRange = new HttpRange(offset, buffer.Length); // offset -> buffer.Length-1 (inclusive)
var resp = file.UploadRange(httpRange, uploadChunk);
Console.WriteLine($"Wrote bytes {offset}-{offset+(buffer.Length-1)} to {fullPath}. Response: {resp.GetRawResponse()}");
offset += buffer.Length; // Shift the offset by number of bytes already written
}
reader.Close();
}
else
{
throw new Exception($"Failed to create directory: {dirName}");
}
}
catch (Exception e)
{
// Close out memory stream
throw new Exception($"Error occured while writing file from stream: {e.Message}");
}
}
Any help on this is greatly appreciated.

finding file in root of wpf application

I'm trying to load a file with pack://application: The file is situated in the root of my project but I keep getting a null reference error. However When I do an absolute reference it finds the file and loads just fine.
What am I missing here?
This doesn't work
var txt = Application.GetContentStream(new Uri(#"pack://application:,,,/Layout.xml"));
string full = new StreamReader(txt.Stream).ReadToEnd();
or any variation with Pack://Application,,,/
This works, but I don't want to use it and seems bad practice anyway
var path = AppDomain.CurrentDomain.BaseDirectory.Substring(0, (AppDomain.CurrentDomain.BaseDirectory.Length - 10));
var txt = path + #"Layout.xml";
string full = new StreamReader(txt).ReadToEnd();
First, ensure that the file is definitely copied into your output ./bin/ directory on compile:
This worked perfectly for me in my WPF application:
const string imagePath = #"pack://application:,,,/Test.txt";
StreamResourceInfo imageInfo = Application.GetResourceStream(new Uri(imagePath));
byte[] imageBytes = ReadFully(imageInfo.Stream);
If you want to read it as binary (e.g. read an image file), you'll need this helper function. You probably won't need this, as you're reading an .xml file.
public static byte[] ReadFully(Stream input)
{
byte[] buffer = new byte[16 * 1024];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
return ms.ToArray();
}
}
For more, see Microsoft on Pack URIs in WPF.
I'm not familiar with the way you are trying to achieve this. I use to solve this kind of problem differently:
First, embed the file you are trying to access in you application. This is done by setting the Build-Step-Property of the File (Properties-Window, when file is selected in VS) to Embedded Resource.
In your application, you can recieve a stream to that resource like that:
var stream = this.GetType().Assembly.GetManifestResourceStream("Namespace.yourfile.txt");
If you are unsure of the string you have to pass to GetManifestResourceStream(..), you can inspect what embedded resources are available and look for the one that is accociated with your file like so:
var embeddedResources = this.GetType().Assembly.GetManifestResourceNames()

Checking if the file is rar through its bytes

I am trying to verify that the file is a .rar file through its bytes for security purposes. Th following code is my code the only problem is that the sub-header is not matching with the one generated from the file. I noticed that is different for different file. Could you please explain to me why?
static bool IsRARFile(string filePath)
{
bool isDocFile = false;
//
// File sigs from: http://www.garykessler.net/library/file_sigs.html
//
string msOfficeHeader = "52-61-72-21-1A-07-00-CF";
string docSubHeader = "64-2E-63-73";
using (Stream stream = File.OpenRead(filePath))
{
//get file header
byte[] headerBuffer = new byte[8];
stream.Read(headerBuffer, 0, headerBuffer.Length);
string headerString = BitConverter.ToString(headerBuffer);
if (headerString.Equals(msOfficeHeader, StringComparison.InvariantCultureIgnoreCase))
{
//get subheader
byte[] subHeaderBuffer = new byte[4];
stream.Seek(512, SeekOrigin.Begin);
stream.Read(subHeaderBuffer, 0, subHeaderBuffer.Length);
string subHeaderString = BitConverter.ToString(subHeaderBuffer);
if (subHeaderString.Equals(docSubHeader, StringComparison.InvariantCultureIgnoreCase))
{
isDocFile = true;
}
}
}
return isDocFile;
}
This is because you have just copied a function from somewhere for a different filetype and not every filetype has any notion of a "subheader". You only need to check the main header in the case of RAR.
I also suggest modifying the naming of the variables, it is quite a mismash if a function says it's checking for RAR type and internally all variables refer to DOCs.

Trouble with getting file from dropbox and saving on my server

Here is my java script code to choose file from dropbox, When I try to save this file to server using C# I am able to see file on server but it is empty.when I am trying to open file the file is giving error like 'file is corrupted'. using signalR.
options = {
// Required. Called when a user selects an item in the Chooser.
success: function (files) {
alert("Here's the file link: " + files[0].link)
hub.server.servermethod(files[0].link, files[0].name);
},
// Optional. Called when the user closes the dialog without selecting a file
// and does not include any parameters.
cancel: function () {
},
// Optional. "preview" (default) is a preview link to the document for sharing,
// "direct" is an expiring link to download the contents of the file. For more
// information about link types, see Link types below.
linkType: "preview", // or "direct"
// Optional. A value of false (default) limits selection to a single file, while
// true enables multiple file selection.
multiselect: false, // or true
// Optional. This is a list of file extensions. If specified, the user will
// only be able to select files with these extensions. You may also specify
// file types, such as "video" or "images" in the list. For more information,
// see File types below. By default, all extensions are allowed.
extensions: ['.csv', '.xls', '.tsv', '.xlsx', '.txt'],
};
var button = Dropbox.createChooseButton(options);
$('#container').append(button);
function some() {
Dropbox.choose(options);
}
server Method code is
// execute the request
HttpWebResponse response = (HttpWebResponse)
request.GetResponse();
// we will read data via the response stream
Stream resStream = response.GetResponseStream();
string tempString = null;
int count = 0;
Byte[] buffer = new Byte[32 * 1024];
StringBuilder sb = new StringBuilder();
do
{
// fill the buffer with data
count = resStream.Read(buffer, 0, buffer.Length);
// make sure we read some data
if (count != 0)
{
// translate from bytes to ASCII text
tempString = Encoding.ASCII.GetString(buffer, 0, count);
// continue building the string
sb.Append(tempString);
}
}
while (count > 0); // any more data to read?
using (FileStream fs = File.Create(System.Configuration.ConfigurationManager.AppSettings.GetValues("DocumentPath").First().ToString() + fileName))
{
// Byte[] bufer = new Byte[32 * 1024];
fs.Write(buffer, 0, buffer.Length);
}
You're setting linkType to "preview", which gives you a link to a preview page for the file, and not the file content itself. If you want direct access to the file content, e.g., to immediately and programmatically download the content to your server, as it seems you're trying to do, you should use the "direct" linkType.

Categories

Resources