Decode LZMA2 file with .xz extension using 7zip SDK - c#

I need to decode .xz file created with 7zip. Compression alghorithm is LZMA2. How should I use 7zip SDK for C# to solve this problem?
I already tried with this code, but it didn't work:
var coder = new SevenZip.Compression.LZMA.Decoder();
var input = new MemoryStream(); // filled with byte array of .xz file
var output = new MemoryStream();
// Read the decoder properties
byte[] properties = new byte[5];
zipFile.Read(properties, 0, 5);
// Read in the decompress file size.
byte[] fileLengthBytes = new byte[8];
zipFile.Read(fileLengthBytes, 0, 8);
long fileLength = BitConverter.ToInt64(fileLengthBytes, 0);
coder.SetDecoderProperties(properties); // this throws exception
coder.Code(zipFile, output, zipFile.Length, fileLength, null);
output.Flush();
output.Close();
I marked a line which causes exception.

Related

unexpected char when parsing json string

I am serializing an object to a stream to store as file and then retrieving and trying to deserialize the object, but get an error parsing. Below is code:
var content = JsonConvert.SerializeObject(data);
var output = new MemoryStream();
var writer = new StreamWriter(output, Encoding.UTF8);
writer.Write(content);
writer.Flush();
//write to some file...
//when reading the file
Stream filestream;
//filestream opens some file stream
byte[] buffer = new byte[4096]
using(MemoryStream ms = new MemoryStream()){
int read;
while((read = filestream.Read(buffer, 0, buffer.Length)) > 0){
ms.Write(buffer, 0, read);
}
var data = Encoding.UTF8.GetString(ms.ToArray());
//encounters error here. I can see that first few chars of the string are question marks.
JsonConvert.DeserializeObject<T>(data);
A couple ideas. Are you getting an exception?
Try encapsulating your write & reads into functions and wrap the memoryStream and streamWriter in using statements as well
using var writer = new StreamWriter(...
Additionally you don't need to set the length of the buffer to 4096, that's probably messing up your encoding. Read your memorystream to an array like so
var buffer = ms.ToArray();
How can I write MemoryStream to byte[]
It looks like you're having an issue copying the memory between the 2 memory streams though. Ideally you would write and read to a file or some other source rather than between 2 memory stream objects but you can copy the contents directly using a copyto
https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.copyto?view=net-6.0
Edit: Adding pseudocode
Assuming your content has been read into
Stream filestream;
using var MemoryStream ms = new MemoryStream();
filestream.CopyTo(ms);
var data = Encoding.UTF8.GetString(ms.ToArray());
return JsonConvert.DeserializeObject<T>(data);

c# - Create and upload csv file to ADLS

I am trying to create a .csv file to upload into ADLS using DataLakeFileClient and MemoryStream. It works fine but the csv file has a garbage value after each letter in the csv. (I can see those as 'NUL's when I download and open the file in notepad++).
Here is my code:
DataLakeFileClient fileClient = new DataLakeFileClient(new
Uri($"https://{accountName}.dfs.core.windows.net/{container}/{directory}/{filename}"), credential);
UnicodeEncoding uniEncoding = new UnicodeEncoding();
using (MemoryStream memStream = new MemoryStream(100))
{
byte[] colString = uniEncoding.GetBytes("a,b,c,d,e,f");
memStream.Write(colString, 0, colString.Length);
memStream.WriteByte(0x0A);
byte[] dataString = uniEncoding.GetBytes(string.Join(",", "val1","val2","val3","val4","val5","val6"));
memStream.Write(dataString, 0, dataString.Length);
memStream.Position = 0;
fileClient.Upload(memStream);
}
It's because your LF (0x0A) is one byte instead of 2.
Add after it another byte:
memStream.WriteByte(0x0A);
memStream.WriteByte(0x0);

Audio Stream to Base64 String issue in Windows Phone

I am creating Windows Phone 8.1 app, I have created Audio Recorder module, and converting audio stream to Base64String, but my resulting Base64String is given below:
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
For exact idea, see my code below:
public void UpdateWavHeader()
{
if (!stream.CanSeek) throw new Exception("Can't seek stream to update wav header");
var oldPos = stream.Position;
stream.Seek(4, SeekOrigin.Begin);
stream.Write(BitConverter.GetBytes((int)stream.Length - 8), 0, 4);
stream.Seek(40, SeekOrigin.Begin);
stream.Write(BitConverter.GetBytes((int)stream.Length - 44), 0, 4);
stream.Seek(oldPos, SeekOrigin.Begin);
IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication();
string isoVideoFileName = "DemoFile.aac";
if (isf.FileExists(isoVideoFileName))
{
isf.DeleteFile(isoVideoFileName);
}
isoVideoFile = new IsolatedStorageFileStream(isoVideoFileName, FileMode.Create, IsolatedStorageFile.GetUserStoreForApplication());
isoVideoFile.Write(stream.ToArray(), 0, stream.ToArray().Length);
byte[] chunk = new byte[isoVideoFile.Length];
string base64String = Convert.ToBase64String(chunk);
}
Take a look at these two lines in your code:
byte[] chunk = new byte[isoVideoFile.Length];
string base64String = Convert.ToBase64String(chunk);
You are basicly encoding a byte array initialized to zero's.
EDIT:
Assuming you want to encode the stream you are writing to the .aac file, this should do the trick:
var chunk = stream.ToArray();
isoVideoFile = new IsolatedStorageFileStream(isoVideoFileName, FileMode.Create, IsolatedStorageFile.GetUserStoreForApplication());
isoVideoFile.Write(chunk, 0, chunk.Length);
//byte[] chunk = new byte[isoVideoFile.Length];
string base64String = Convert.ToBase64String(chunk);

Convert open xml string to byte[]

so, I am editing a word document, using OpenXML. And for some reasons, I convert it all into a string:
//conversion du byte en memorystream
using (var file = new MemoryStream(text))
using (var reader = new StreamReader(file))
{
WordprocessingDocument wordDoc = WordprocessingDocument.Open(file, true);
using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
{
docText = sr.ReadToEnd();
}
}
And then, I convert it as a byte.
But, a simple convert will not work:
byte[] back2Byte = System.Text.Encoding.ASCII.GetBytes(docText );
Because the string is a open xml string.
Tried this, but always got a corrupted file when I tried to open it with Word:
var repo = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(docText));
byte[] buffer = new byte[16 * 1024];
MemoryStream ms = new MemoryStream();
int read;
while ((read = repo.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
byte[] back2Byte = ms.ToArray();
So, this doesn't work either:
byte[] back2Byte = new byte[docText.Length * sizeof(char)];
System.Buffer.BlockCopy(docText.ToCharArray(), 0, back2Byte, 0, back2Byte.Length);
edit : After some checkings, it seems it is write as a openxml document into the database, and so, word cannot read it. There is no error when i open it with notepad
How can I correct this?
So, the real issue is, how can I convert a OpenXML string to a byte that can be open in word?
You cannot do this sort of thing. You are getting the bytes for only one part of an OpenXML document. By definition, all Microsoft Office documents are multi-part OpenXML documents. You could theoretically capture the bytes for all the parts using a technique like you're currently using, but you would also have to capture all the part/relationship information necessary to reconstruct the multi-part document. You'd be better off just reading all the bytes of the file and storing them as-is:
// to read the file as bytes
var fileName = #"C:\path\to\the\file.xlsx";
var fileBytes = File.ReadAllBytes(fileName);
// to recreate the file from the bytes
File.WriteAllBytes(fileName, fileBytes)
If you need a string form of those bytes, try this:
// to convert bytes to a (non-readable) text form
var fileContent = Convert.ToBase64String(fileBytes);
// to convert base-64 back to bytes
var fileBytes = Convert.FromBase64String(fileContent);
Either way, there is absolutely no need to use the OpenXML SDK for your use case.

Original file bytes from StreamReader, magic number detection

I'm trying to differentiate between "text files" and "binary" files, as I would effectively like to ignore files with "unreadable" contents.
I have a file that I believe is a GZIP archive. I'm tring to ignore this kind of file by detecting the magic numbers / file signature. If I open the file with the Hex editor plugin in Notepad++ I can see the first three hex codes are 1f 8b 08.
However if I read the file using a StreamReader, I'm not sure how to get to the original bytes..
using (var streamReader = new StreamReader(#"C:\file"))
{
char[] buffer = new char[10];
streamReader.Read(buffer, 0, 10);
var s = new String(buffer);
byte[] bytes = new byte[6];
System.Buffer.BlockCopy(s.ToCharArray(), 0, bytes, 0, 6);
var hex = BitConverter.ToString(bytes);
var otherhex = BitConverter.ToString(System.Text.Encoding.UTF8.GetBytes(s.ToCharArray()));
}
At the end of the using statement I have the following variable values:
hex: "1F-00-FD-FF-08-00"
otherhex: "1F-EF-BF-BD-08-00-EF-BF-BD-EF-BF-BD-0A-51-02-03"
Neither of which start with the hex values shown in Notepad++.
Is it possible to get the original bytes from the result of reading a file via StreamReader?
Your code tries to change a binary buffer into a string. Strings are Unicode in NET so two bytes are required. The resulting is a bit unpredictable as you can see.
Just use a BinaryReader and its ReadBytes method
using(FileStream fs = new FileStream(#"C:\file", FileMode.Open, FileAccess.Read))
{
using (var reader = new BinaryReader(fs, new ASCIIEncoding()))
{
byte[] buffer = new byte[10];
buffer = reader.ReadBytes(10);
if(buffer[0] == 31 && buffer[1] == 139 && buffer[2] == 8)
// you have a signature match....
}
}
Usage (for a pdf file):
Assert.AreEqual("25504446", GetMagicNumbers(filePath, 4));
Method GetMagicNumbers:
private static string GetMagicNumbers(string filepath, int bytesCount)
{
// https://en.wikipedia.org/wiki/List_of_file_signatures
byte[] buffer;
using (var fs = new FileStream(filepath, FileMode.Open, FileAccess.Read))
using (var reader = new BinaryReader(fs))
buffer = reader.ReadBytes(bytesCount);
var hex = BitConverter.ToString(buffer);
return hex.Replace("-", String.Empty).ToLower();
}
You can't. StreamReader is made to read text, not binary. Use the Stream directly to read bytes. In your case FileStream.
To guess whether a file is text or binary you could read the first 4K into a byte[] and interpret that.
Btw, you tried to force chars into bytes. This is invalid by principle. I suggest you familiarize yourself with what an Encoding is: it is the only way to convert between chars and bytes in a semantically correct way.

Categories

Resources