getting NegativeByteArraySizeException from ContentResolver's openAssetFileDescriptor method for reading vCardUri. Is there any workaround to fix it? - file-descriptor

I am creating a .VCF file for backing up the Contacts. The process of creating and inserting the data get failed because of the FileDescriptor's method getDeclaredLength which returns the size -1 for the length of the vCard-URI which I got from the ContentResolver's openAssetFileDiscritor method.
This is the exact same Question as asked here by Balakrishna Avulapati. but the only problem for asking the same question here is that, the proposed solution is a bit hard for me to understand. which do not salve my problem. The comment by #pskink in the solution of above link could be useful but i am anable to find the full source code, as there is only 1 line provided in the comment.
I am using the fllowing code,
Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey);
AssetFileDescriptor fd = resolver.openAssetFileDescriptor(uri, "r");
FileInputStream fis = fd.createInputStream();
byte[] b = new byte[(int)fd.getDeclaredLength()];
fis.read(b);
Please give your kind sugestions. Thank you :)

So I figured it out by myself, and I'm posting the answer in case of somebody get the similar problem and stuck for the solution. So the code before byte[] b = new byte[(int)fd.getDeclaredLength()]; is same. Change this line to byte[] buf = readBytes(fis); and the method readBytes(FileInputStream fis) is below.
public byte[] readBytes(InputStream inputStream) throws IOException {
// this dynamically extends to take the bytes you read
ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
// this is storage overwritten on each iteration with bytes
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
// we need to know how may bytes were read to write them to the byteBuffer
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
byteBuffer.write(buffer, 0, len);
}
// and then we can return your byte array.
return byteBuffer.toByteArray();
}
Hope this help. Cheers

Related

java : What is the exact functionality of buffer.flip() method?

try (FileOutputStream binFile = new FileOutputStream("data.dat");
FileChannel binChannel = binFile.getChannel()) {
ByteBuffer buffer = ByteBuffer.allocate(100);
byte[] outputBytes = "Hello World!".getBytes();
buffer.put(outputBytes);
long int1Pos = outputBytes.length;
buffer.putInt(245);
binChannel.write(buffer);
java.io.RandomAccessFile ra = new java.io.RandomAccessFile("data.dat", "rwd");
FileChannel channel = ra.getChannel();
ByteBuffer readBuffer = ByteBuffer.allocate(100);
channel.position(int1Pos);
channel.read(readBuffer);
readBuffer.flip();
System.out.println("Int3 = " + readBuffer.getInt());
} catch(IOException e){
}
You should checkout the Java docs on it. https://docs.oracle.com/javase/7/docs/api/java/nio/Buffer.html
Flips this buffer. The limit is set to the current position and then the position is set to zero. If the mark is defined then it is discarded.
After a sequence of channel-read or put operations, invoke this method to prepare for a sequence of channel-write or relative get operations. For example:

Azure Page Blob OpenRead does not fetch more than StreamMinimumReadSizeInBytes

I have a page blob containing effectively log data. Everything works fine until the log fills up past 2 MB.
When Reading, I'm using the OpenReadAsync method to get a stream from which I read data out of. Prior to calling OpenReadAsync, I set StreamMinimumReadSizeInBytes to 2MB (2 * 1024 * 1024).
After opening the stream, I use the following method to read data out.
public IEnumerable<object> Read(Stream pageAlignedEventStream, long? maxBytes = null)
{
while (pageAlignedEventStream.Position < (maxBytes ?? pageAlignedEventStream.Length))
{
byte[] bytesToReadBuffer = new byte[LongZero.Length];
pageAlignedEventStream.Read(bytesToReadBuffer, 0, LongZero.Length);
long bytesToRead = BitConverter.ToInt64(bytesToReadBuffer, 0);
if (bytesToRead == 0)
{
yield break;
}
if (bytesToRead < 0)
{
throw new InvalidOperationException("Invalid size specification. Stream may be corrupted.");
}
if (bytesToRead > Int32.MaxValue)
{
throw new InvalidOperationException("Payload size is too large.");
}
byte[] payload = new byte[bytesToRead];
int read = pageAlignedEventStream.Read(payload, 0, (int) bytesToRead);
if (read != bytesToRead)
{
// when fails, read == 503, bytesToRead = 3575, position = 2MB (2*1024*14024)
throw new InvalidOperationException("Did not read expected number of bytes.");
}
yield return this.EventSerializer.DeserializeFromStream(new MemoryStream(payload, false));
var paddedSpaceToSkip = PagesRequired(bytesToRead) * PageSizeBytes - bytesToRead - LongZero.Length;
pageAlignedEventStream.Position += paddedSpaceToSkip;
}
yield break;
}
As noted in the comments in the code, the failure happends when the position reaches the 2MB specified. The read fails to pull additional bytes before returning and only reads 503 bytes instead of the expected 3575 bytes.
My expectation was that as I read past the buffer size, it would download more data.
I found a similar issue on Azure Feedback, but linked issue indicates a non-power-of-2 buffersize but 2MB is definitely power of 2.
I could fetch the all data (Size=3MB) that stored in a page blob even though I set StreamMinimumReadSizeInBytes property of CloudPageBlob to 2MB.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
CloudConfigurationManager.GetSetting("StorageConnectionString"));
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("mycontainername");
container.CreateIfNotExists();
CloudPageBlob pageBlob = container.GetPageBlobReference("mypageblob");
pageBlob.StreamMinimumReadSizeInBytes = 2 * 1024 * 1024;
Task<Stream> pageAlignedEventStream = pageBlob.OpenReadAsync();
The read fails to pull additional bytes before returning and only reads 503 bytes instead of the expected 3575 bytes.
If that many bytes are not currently available and the end of the stream has been reached, the returned value could be less than the number of bytes requested. Please debug your code to trace the changes of variable of paddedSpaceToSkip and check whether your code logic is as expected.

Covert xamarin.image into base 64 format

I need to Convert a xamarin forms image into a base64 format, Can anyone help me with this?
This is how i've being trying to do it, but it doesent work.
var inputStream = signatureImage.Source.GetValue(UriImageSource.UriProperty);
//Getting Stream as a Memorystream
var signatureMemoryStream = inputStream as MemoryStream;
if (signatureMemoryStream == null)
{
signatureMemoryStream = new MemoryStream();
inputStream.CopyTo(signatureMemoryStream);
}
//Adding memorystream into a byte array
var byteArray = signatureMemoryStream.ToArray();
//Converting byte array into Base64 string
base64String = Convert.ToBase64String(byteArray);
"signatureImage" is the image name.
Once you get your file path , you can use the following code that worked for me.
var stream = file.GetStream();
var bytes = new byte [stream.Length];
await stream.ReadAsync(bytes, 0, (int)stream.Length);
string base64 = System.Convert.ToBase64String(bytes);
I found it here
Image is just a control in Xamarin forms to display the image.
It is not something from which you can get your image byte array out.
You will be better of using the Media Plugin and save it to disk. Then load it via memory stream and convert.
You can also use FFImageLoading. It has 2 methods which can be of use for you :
GetImageAsJpgAsync(int quality = 90, int desiredWidth = 0, int desiredHeight = 0)
GetImageAsPngAsync(int desiredWidth = 0, int desiredHeight = 0)
The SO question - Convert Image into byte array in Xamarin.Forms shows how to do it in Platform specific code here.
The forum thread (Convert Image to byte[]) has a good discussion on why you can't get it from the control.
You can do this as below as well
var base64String = Convert.ToBase64String(File.ReadAllBytes(file.Path))

In C# VS2013 how do you read a resource txt file one line at a time?

static void Starter(ref int[,] grid)
{
StreamReader reader = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream(Resources.Sudoku));
string line = reader.ReadLine();
Console.Write(line);
Console.ReadLine();
}
I know this isn't right, but it gets my point across.
I would like to be able to read in the resource file one line at a time.
Like so:
System.IO.StreamReader StringFromTxt
= new System.IO.StreamReader(path);
string line = StringFromTxt.ReadLine();
I do not necessarily have to read in from the resource, but I am not sure of any other way to call a text file without knowing the directory every time, or hard coding it. I can't have the user pick files.
StreamReader sr = new StreamReader("D:\\CountryCodew.txt");
while (!sr.EndOfStream)
{
string line = sr.ReadLine();
}
MSDN lists the following as the way to read in one line at a time:
https://msdn.microsoft.com/en-us/library/aa287535(v=vs.71).aspx
int counter = 0; //keep track of #lines read
string line;
// Read the file and display it line by line.
System.IO.StreamReader file =
new System.IO.StreamReader("c:\\test.txt");
while((line = file.ReadLine()) != null)
{
Console.WriteLine (line);
counter++;
}
file.Close();
// Suspend the screen.
Console.ReadLine();
Additional examples for getline:
https://msdn.microsoft.com/en-us/library/2whx1zkx.aspx

Image to Byte array conversion

I need to convert image to Byte array as I have to upload to server, have seen many articles but i am not able to understand ho wit is done, forgive me if you think my question is up-to be asked in this forum
If you have a WriteableBitmap, for example called LoadedPhoto, you can try:
using (MemoryStream ms = new MemoryStream()
{
LoadedPhoto.SaveJpeg(ms, LoadedPhoto.PixelWidth, LoadedPhoto.PixelHeight, 0, 95);
ms.Seek(0, 0);
byte[] data = new byte[ms.Length];
ms.Read(data, 0, data.Length);
ms.Close();
}
If you're using WriteableBitmapEx library from CodePlex, it can do a conversion to byte array, too
http://writeablebitmapex.codeplex.com/
I assume that it is a Bitmap (however it works for all image types) :
System.Drawing.Bitmap bmp = GetYourImage();
System.IO.MemoryStream stream = new System.IO.MemoryStream();
bmp.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp);
stream.Position = 0;
byte[] data = stream.ToArray();

Resources