How do I read from a GZIPInputStream in Xamarin.android? - xamarin

I have a an Array of bytes byteArray which contains data compressed with Gzip. I want to read the whole array and decode the data using the appropriate encoding ("ISO-8859-15").
GZIPInputStream gzipInputStream = new GZIPInputStream(new MemoryStream(personalDataArray));
InputStreamReader inputStream = new InputStreamReader(gzipInputStream);
However I get a compiler error when trying to read the gzip input stream with an Input stream reader, it says cannot convert from Java.Util.Zip.GZipInputStream to System.IO.Stream. This issue does not occur in Java though. How do I get around this? How do I specify the encoding to be used too? Thanks.

You can use this method to decompress GZip, use GZipStream
Here you have Xamarin doc. about System.IO.Compression.GZipStream Class
static byte[] Decompress(byte[] data)
{
using (var compressedStream = new MemoryStream(data))
using (var zipStream = new GZipStream(compressedStream, CompressionMode.Decompress))
using (var resultStream = new MemoryStream())
{
zipStream.CopyTo(resultStream);
return resultStream.ToArray();
}
}
And you can read it using Encoding.UTF8.GetString(),
var msg = Encoding.UTF8.GetString(Decompress(personalDataArray));
Also You have to convert UTF-8 to ISO-8859-15 (Latin9), this sample is for ISO-8859-1 (Latin1), but try with ISO-8859-15.
var strISO88591= Encoding.GetEncoding("ISO-8859-1")
.GetString(Encoding.Conver‌​t(Encoding.UTF8,Encoding.GetEncoding("ISO-8859-1"), Encoding.UTF8.GetBytes(msg)));

Related

Unable to download PDF file, fetched from Sql Database.Bytes value has been fetched, Function doesn't through any error, But PDF is not downloaded

I am unable to download a PDF file, fetched from Sql Database. Bytes value has been fetched, Function doesn't throw any error, but the PDF is not downloaded.
Code:
public ActionResult PrintPDF(string projectSelection)
{
byte[] extract = (byte[])_selectionManager.FindPdf();
MemoryStream pdfStream = new MemoryStream();
pdfStream.Write(extract, 0, extract.Length);
pdfStream.Position = 0;
HttpContext.Response.AddHeader("content-disposition",
"attachment; filename=form.pdf");
return new FileStreamResult(pdfStream, "application/pdf");
}
Since you already have the file content as bytes, why converting it to stream ?
Please check if this works
byte[] extract = (byte[])_selectionManager.FindPdf();
return File(
extract, System.Net.Mime.MediaTypeNames.Application.Pdf, "form.pdf");

Indexing PDF file in ElasticSearch using Java Code

I am trying to Index PDF files in elastic search 6.3.2 using Java code. So far I have written following code to save the pdf in ES. The code is working fine and I am able to save the Base64 encoded string of my PDF in ES. I want to understand if the approach which I am following is correct or not? Is there any better way of doing it?
Following is my code:
InputStream inputStream = new FileInputStream(new File("mypdf.pdf"));
try {
byte[] fileByteStream = IOUtils.toByteArray(inputStream );
String base64String = new String(Base64.getEncoder().encodeToString(fileByteStream).getBytes(),"UTF-8");
String strEncoded = Base64.getEncoder().encodeToString( base64String.getBytes( "utf-8" ));
this.stream.close();
JSONObject correspondenceNode = new JSONObject();
correspondenceNode.put("data",strEncoded );
String strSsonValues = correspondenceNode.toString();
HttpEntity entity = new NStringEntity(strSsonValues , ContentType.APPLICATION_JSON);
elasticrestClient.put("/2018/documents/"1, entity);
} catch (IOException e) {
e.printStackTrace();
}
Basically what I am doing here is, I am converting the PDF document into Base64String and saving it into ES and while reading, I am converting it back.
following is the code for decoding:
String responseBody = elasticrestClient.get("/2018/documents/1");
//some code to fetch the hits
JSONObject h = hitsArray.getJSONObject(0);
source = h.getJSONObject("_source");
String object = (source.getString("data"));
byte[] decodedStr = Base64.getDecoder().decode( object );
FileOutputStream fos = new FileOutputStream("download.pdf");
fos.write(Base64.getDecoder().decode(new String( decodedStr, "utf-8" )));
fos.close();
This might be correct to store a BASE64 content in elasticsearch but few pieces might be missing here:
You are not "indexing" the PDF as per say in Elasticsearch. If you want to do so, you need to define an ingest pipeline and use the ingest attachment plugin to extract the content from the PDF.
You did not speak about the mapping you are using. If you "really" want to keep the binary content around, you might want to define the BASE64 field as a binary data type.
It does not sound to me a good idea to use elasticsearch to store large blobs like this.
Instead, I'd extract text and metadata and index that + an URL to the binary itself. Like:
{
"content": "Extracted text here",
"meta": {
// Meta data there
},
"url": "file://path/to/file"
}
You can also look at FSCrawler (including its code) which does basically that.

xamarin.forms get byte array from imagesource

I have svg xml that i can convert to ImageSource or FileImageSource by using XamSVG library in the PCL project of my xamarin.forms.
I want to convert the ImageSource / FileImageSource to byte array (to get the bitmap).
Is this possible ?
ImageSource doesn't expose any mechanism to retrieve the original image source. Instead, you will need to manually keep a reference to the original source you use to create the image.
I've found the solution.
StreamImageSource streamImageSource = (StreamImageSource) some image source...
System.Threading.CancellationToken cancellationToken = System.Threading.CancellationToken.None;
Task<Stream> task = streamImageSource.Stream(cancellationToken);
Stream stream = task.Result;
Another solution:
public static byte[] ReadFully(Stream input)
{
using (MemoryStream ms = new MemoryStream())
{
input.CopyTo(ms);
return ms.ToArray();
}
}
Stream and MemoryStream are System.IO classes.
Then use it like this:
byte[] TargetImageByte = ReadFully(_data.Source);
_data.source is MediaFile type.

Web API - Setting Response.Content with byte[] / MemoryStream Contents not working properly

My requirement is to use Web API to send across the network, a zip file (consisting a bunch of files in turn) which should not be written anywhere locally (not written anywhere on the server/client disk). For zipping, I am using DotNetZip - Ionic.Zip.dll
Code at Server:
public async Task<IHttpActionResult> GenerateZip(Dictionary<string, StringBuilder> fileList)
{
// fileList is actually a dictionary of “FileName”,”FileContent”
byte[] data;
using (ZipFile zip = new ZipFile())
{
foreach (var item in filelist.ToArray())
{
zip.AddEntry(item.Key, item.Value.ToString());
}
using (MemoryStream ms = new MemoryStream())
{
zip.Save(ms);
data = ms.ToArray();
}
}
var result = new HttpResponseMessage(HttpStatusCode.OK);
MemoryStream streams = new MemoryStream(data);
//, 0, data.Length-1, true, false);
streams.Position = 0;
//Encoding UTFEncode = new UTF8Encoding();
//string res = UTFEncode.GetString(data);
//result.Content = new StringContent(res, Encoding.UTF8, "application/zip");
<result.Content = new StreamContent(streams);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/zip");
//result.Content.Headers.ContentLength = data.Length;
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentDisposition.FileName = "test.zip";
return this.Ok(result);
}
The issue I am facing is that after the zip file downloaded at client end when modified as a test.bin has its stream contents (byte[] data in this example’s contents) missing. (I am getting back a test.zip file. When I change the file locally from test.zip to test.bin, I am seeing that the File’s contents as shown below. It does not contain the Response.Content values. P.S. I have also tried the MIME type “application/octet-stream” as well. No luck!)
Test.zip aka test.bin’s contents:
{"version":{"major":1,"minor":1,"build":-1,"revision":-1,"majorRevision":-1,"minorRevision":-1},
"content":{"headers":[{"key":"Content-Type","value":["application/zip"]},
{"key":"Content-Disposition","value":["attachment; filename=test.zip"]}]},
"statusCode":200,"reasonPhrase":"OK","headers":[],"isSuccessStatusCode":true}
Can someone please help me on how we can set result.Content with a MemoryStream object (I have seen example of “FileStream” at other places on google to set “result.Content” but I want to use MemoryStream object only!). I am highlighting this because I think the problem lies with setting the MemoryStream object to the result.Content (in order to properly save the streams content into the result.Content object)
P.S. I have also gone thru Uploading/Downloading Byte Arrays with AngularJS and ASP.NET Web API (and a bunch of other links) but it did not help me much… :(
Any help is greatly appreciated. Thanks a lot in advance :)
I got my issue solved!!
All I did was to change the Response Type to HttpResponseMessage and use "return result" in the last line rather than Ok(result) { i.e. HttpResponseMessage Type rather than OKNegiotatedContentResult Type)

MVC. Itextsharp write pdf to response

I am generating pdf using itexsharp.
I am creating MemoryStream, then when i am trying t write MemoryStream bytes in to response but no luck. When i am executing this code in my controller the pdf not coming in response. Memory stream is populaitng correctly i can see this in debugger, but for some reason this number of butes not coming in response.
Here is my code:
HttpContext.Current.Response.ContentType = "application/pdf";
...
using (Stream inputPdfStream = new FileStream(pdfFilePath, FileMode.Open, FileAccess.Read, FileShare.Read))
using (Stream outputPdfStream = new MemoryStream())
{
PdfReader reader = new PdfReader(inputPdfStream);
PdfStamper stamper = new PdfStamper(reader, outputPdfStream);
....
//try one
outputPdfStream.WriteTo(HttpContext.Current.Response.OutputStream); // NOT POPULATING Response
//try two
HttpContext.Current.Response.BinaryWrite(outputPdfStream.ToArray()); // NOT POPULATING Response Too
HttpContext.Current.Response.End();
}
May be some one have any ideas?
Could you not use
Response.ContentType = "application/pdf"
Response.AddHeader("Content-Type", "application/pdf")
Response.WriteFile(pdfFilePath)
Response.End()
You should use the FileContentResult Controller.File(byte[] content, string contentType) method:
public ActionResult GeneratePDF()
{
var outputStream = new MemoryStream(); // This will hold the pdf you want to send in the response
/*
* ... code here to create the pdf in the outputStrem
*/
return File(outputStream.ToArray(), "application/pdf");
}
Source: Building PDFs in Asp.Net MVC 2.
Probably the memorystream is still set at the position after the last written byte. It will write all bytes from the current position (which is none). If you do a outputPdfStream.Seek(0) it will set the position back to the first byte, and will write the contents of the whole stream to the response output.
Anyway, like Dean says, you should just use the Reponse.WriteFile method.

Resources