Following is the code to first save a line of text,into a text file,present in azure storage, and then read it and print .
string firstString = "this \t is \n a \t line \n are: ";
using (var memoryStream = new MemoryStream())
{
memoryStream.Write(System.Text.Encoding.UTF8.GetBytes(firstString), 0, System.Text.Encoding.UTF8.GetBytes(firstString).Length);
blockBlob.UploadFromStream(memoryStream);
}
string text;
using (var memoryStream = new MemoryStream())
{
blockBlob.DownloadToStream(memoryStream);
text = System.Text.Encoding.UTF8.GetString(memoryStream.ToArray());
Trace.WriteLine(text);
}
Problem is that nothing gets printed in the Trace.Writeline() Statement.
First i thought,that it might be a encoding issue,so i changed the format of my text file from ASCII to UTF8, but still nothing gets printed.
WHat am i missing here,any help is appreciated.
Replace the following line of code:
using (var memoryStream = new MemoryStream())
{
memoryStream.Write(System.Text.Encoding.UTF8.GetBytes(firstString), 0, System.Text.Encoding.UTF8.GetBytes(firstString).Length);
blockBlob.UploadFromStream(memoryStream);
}
with
using (var memoryStream = new MemoryStream())
{
memoryStream.Write(System.Text.Encoding.UTF8.GetBytes(firstString), 0, System.Text.Encoding.UTF8.GetBytes(firstString).Length);
memoryStream.Position = 0;
blob.UploadFromStream(memoryStream);
}
What's happening is that when you write the byte array to memoryStream, you're not resetting the position of stream to 0 thus a 0 byte blob is being uploaded.
When you use MemoryStream you first write to memory and after the write from memory to blob, it is better to write directly to blob, example:
using (var blobStream = blockBlob.OpenWrite())
{
var data = System.Text.Encoding.UTF8.GetBytes(firstString);
blobStream.Write(data, 0, data.Length);
}
Related
I'm trying to upload files to an Azure fileshare using the library Azure.Storage.Files.Shares.
If I don't chunk the file (by making a single UploadRange call) it works fine, but for files over 4Mb I haven't been able to get the chunking working. The file is the same size when downloaded, but won't open in a viewer.
I can't set smaller HttpRanges on a large file as I get a 'request body is too large' error, so I'm splitting the filestream into multiple mini streams and uploading the entire HttpRange of each of these
ShareClient share = new ShareClient(Common.Settings.AppSettings.AzureStorageConnectionString, ShareName());
ShareDirectoryClient directory = share.GetDirectoryClient(directoryName);
ShareFileClient file = directory.GetFileClient(fileKey);
using(FileStream stream = fileInfo.OpenRead())
{
file.Create(stream.Length);
//file.UploadRange(new HttpRange(0, stream.Length), stream);
int blockSize = 128 * 1024;
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;
file.UploadRange(new HttpRange(0, uploadChunk.Length), uploadChunk);
}
reader.Close();
}
The code above uploads without error, but when downloading the image from Azure it is corrupt.
Does anyone have any ideas? Thanks for any help you can provide.
cheers
Steve
I was able to reproduce the issue. Basically the problem is with the following line of code:
new HttpRange(0, uploadChunk.Length)
Essentially you're always setting the content at the same range and that's why the file is getting corrupted.
Please try the code below. It should work. What I did here is defined the HTTP range offset and moving it constantly with number of bytes already written to the file.
using (FileStream stream = fileInfo.OpenRead())
{
file.Create(stream.Length);
//file.UploadRange(new HttpRange(0, stream.Length), stream);
int blockSize = 1 * 1024;
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);
var resp = file.UploadRange(httpRange, uploadChunk);
offset += buffer.Length;//Shift the offset by number of bytes already written
}
reader.Close();
}
I have some trouble with decompress gzip from string in lua. (mb bad understanding)
Response of one web-services is base64-encoded gzip string, for sample I get some code on C#.
public static string Decompress(byte[] value, Encoding Encoding = null)
{
if (value == null) return null;
Encoding = Encoding ?? System.Text.Encoding.Unicode;
using (var inputStream = new MemoryStream(value))
using (var outputStream = new MemoryStream())
{
using (var zip = new GZipStream(inputStream, CompressionMode.Decompress))
{
byte[] bytes = new byte[4096];
int n;
while ((n = zip.Read(bytes, 0, bytes.Length)) != 0)
{
outputStream.Write(bytes, 0, n);
}
zip.Close();
}
return Encoding.GetString(outputStream.ToArray());
}
}
static void Main(string[] args)
{
const string encodedText = "H4sIAAAAAAAEAHMNCvIPUlRwzS0oqVQoLinKzEtXyC9SyCvNyYFxM/OAqKC0RKEgsSgxN7UktQgAwOaxgjUAAAA=";
byte[] decodedBytes = Convert.FromBase64String(encodedText);
var decodedString = Decompress(decodedBytes, Encoding.UTF8);
Console.WriteLine(decodedString);
}
I try to do this with lua (on nginx) and make from base64 string array of byte
local byte_table={};
base64.base64_decode(res_string):gsub(".", function(c){
table.insert(byte_table, string.byte(c))
})
but have some problem with zlib.
Please help me understanding how can I use IO stream in lua and decompress gzip.
I try to do this with lua (on nginx) and make from base64 string array of byte
No, you are making Lua table with bunch of numbers.
Decode base64 and feed to zlib the whole resulting string.
I'm use http://luaforge.net/projects/lzlib/ for gzip decompressing:
local result = zlib.decompress(str,31)
Text I am reading from a XML, which is suppose to be a string with base64 encoded and Gzip compressed. I am following the below steps:
string text = childNodes.Item(i).InnerText.Trim();
byte[] compressed = Convert.FromBase64String(text);
byte[] compressed = Convert.FromBase64String(text);
using (var uncompressed = new MemoryStream())
using (var inStream = new MemoryStream(compressed))
using (var outStream = new GZipStream(inStream, CompressionMode.Decompress))
{
outStream.CopyTo(uncompressed);
var reader = new StreamReader(uncompressed);
uncompressed.Position = 0;
string myStr = reader.ReadToEnd();
Console.WriteLine(myStr);
}
I am getting myStr value as something like :
�\b\0\0\0\0\0\0Ľk��ƒ �Y��ؘX{���z:�n�,ɏ�ek��xϞ�`�\0؍�|\t ��_3�\n(\0$�s.Cb�\0*3++��|
͛ �-7�6�fW\r\t�\b���W\"�\n�ə��L&���Ez�-����E��\t�%���/���O��Q����
i�����]�T�b�<_�dŦ�W۫���ܭn^[X�ϕ��{�"
I am expecting adecoded string. Any hint on this is much appreciated.
Thanks in Advance. :)
i am having an issue when trying to read saved List from binary file back to a List.
the file is encrypted, without encryption i had no problem.
writing method:
private void WriteEncodedFile(FileStream fileStream, MemoryStream memoryStream)
{
StreamReader sr = new StreamReader(memoryStream);
BinaryWriter bw = new BinaryWriter(fileStream);
memoryStream.Seek(0, SeekOrigin.Begin);
string data = sr.ReadToEnd();
var bytes = Encoding.UTF8.GetBytes(data);
for (int i = 0; i < bytes.Length; i++) bytes[i] ^= 0x5a;
bw.Write(Convert.ToBase64String(bytes));
bw.Close();
fileStream.Close();
}
Reading method:
private void ReadEncodedFile(FileStream fileStream, MemoryStream memoryStream)
{
BinaryReader br = new BinaryReader(fileStream);
StreamWriter sw = new StreamWriter(memoryStream);
fileStream.Seek(0, SeekOrigin.Begin);
memoryStream.Seek(0, SeekOrigin.Begin);
string base64 = br.ReadString();
byte[] bytes = Convert.FromBase64String(base64);
for (int i = 0; i < bytes.Length; i++) bytes[i] ^= 0x5a;
string decodedData = Encoding.UTF8.GetString(bytes);
sw.Write(decodedData);
}
when reading the content i can see it in the "decodedData".
however the StreamWriter seems not to write it into the MemoryStream.
any idea?
thanks.
I think you are simply not flushing/closing the stream before checking.
sw.Flush();
or
sw.Close();
if done
and
fileStream.Close(); for good practice too
Edit:
Considering the comment, you need to seek to start of memory stream again before deserialising
i.e. memoryStream.Seek(0, SeekOrigin.Begin); where-ever you do it
I'm having a Windows 8 app which is working pretty well and now I want to write the same app for Windows Phone 8, but I'm only getting a black image and not the right image.
This is my code for uploading the image file
if ((_fileType == ".jpg" || _fileType == ".png" || _fileType == ".jpeg") && _fileSize < 3500000)
{
byte[] myPicArray = ConvertToBytes(_bmpFile);
HttpClient httpClient = new HttpClient();
httpClient.BaseAddress = new Uri(MYURI);
MultipartFormDataContent form = new MultipartFormDataContent();
HttpContent content = new ByteArrayContent(myPicArray);
form.Add(content, "media", _randomStringFileName + _fileType);
HttpResponseMessage response = await httpClient.PostAsync("upload.php", form);
}
and this is the code for converting my image to a byte array
private byte[] ConvertToBytes(BitmapImage bitmapImage)
{
using (MemoryStream ms = new MemoryStream())
{
WriteableBitmap btmMap = new WriteableBitmap
(bitmapImage.PixelWidth, bitmapImage.PixelHeight);
// write an image into the stream
Extensions.SaveJpeg(btmMap, ms,
bitmapImage.PixelWidth, bitmapImage.PixelHeight, 0, 100);
return ms.ToArray();
}
}
Has anybody an idea why I'm only getting a black image and not the right image? The image was selected by the PhotoChooseTask.
The PhotoChooseTask already gives you the Stream, so you'll just need to use that instead (You can't use the BitMap yet because it's still busy writing it to the device and generating thumbnails, etc)
PhotoResult photoResult = e as PhotoResult;
MemoryStream memoryStream = new MemoryStream();
photoResult.ChosenPhoto.CopyTo(memoryStream);
byte[] myPicArray = memoryStream.ToArray();