Writing byte array to GAE Blobstore - google-app-engine

I'm able to read the bytes and print it out on System console. However since GAE does not support file creation, I search through StackOverflow and found out that I can write into GAE blobstore. But I'm not sure how to go about doing it as I'm new to GAE..
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.setContentType("text/html;charset=UTF-8");
// resp.setContentType("text/plain");
PrintWriter out = resp.getWriter();
try {
ServletFileUpload upload = new ServletFileUpload();
FileItemIterator iterator = upload.getItemIterator(req);
// out.println("<html><body>");
while (iterator.hasNext()) {
FileItemStream item = iterator.next();
InputStream in = item.openStream();
if (item.isFormField()) {
out.println("<br />Got a form field: " + item.getFieldName());
} else {
out.println("<br />Got an uploaded file: " + item.getFieldName() + ", name = " + item.getName());
ZipInputStream zis = new ZipInputStream(
new BufferedInputStream( in ));
ZipEntry entry;
// Read each entry from the ZipInputStream until no
// more entry found indicated by a null return value
// of the getNextEntry() method.
byte[] buf = new byte[10244];
int len;
while ((entry = zis.getNextEntry()) != null) {
out.println("Unzipping: " + entry.getName());
FileService fileService = FileServiceFactory.getFileService();
AppEngineFile file = fileService.createNewBlobFile("text/plain");
boolean lock = false;
FileWriteChannel writeChannel = fileService.openWriteChannel(file, lock);
PrintWriter outter = new PrintWriter(Channels.newWriter(writeChannel, "UTF8"));
StringBuilder sb = new StringBuilder(buf.length);
if (entry.getName().equalsIgnoreCase("booking.csv")) {
int count = 0;
while ((len = zis.read(buf, 0, buf.length)) != -1) {
//I'm trying to write byte[] into blobstore instead of printing using
//System.out.write(buf, 0, len);
}
Any advice?

Try this:
FileWriteChannel writeChannel = fileService.openWriteChannel(file, lock);
while ((len = zis.read(buf, 0, buf.length)) != -1) {
writeChannel. write(ByteBuffer.wrap(buf, 0, len), null);
}

Easiest way:
import com.google.appengine.api.files.FileService;
import com.google.appengine.api.files.AppEngineFile;
import com.google.appengine.api.files.FileWriteChannel;
import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.images.ImagesServiceFactory;
import com.google.appengine.api.images.ServingUrlOptions;
...
// your data in byte[] format
byte[] data = image.getData();
/**
* MIME Type for
* JPG use "image/jpeg" for PNG use "image/png"
* PDF use "application/pdf"
* see more: https://en.wikipedia.org/wiki/Internet_media_type
*/
String mimeType = "image/jpeg";
// save data to Google App Engine Blobstore
FileService fileService = FileServiceFactory.getFileService();
AppEngineFile file = fileService.createNewBlobFile(mimeType);
FileWriteChannel writeChannel = fileService.openWriteChannel(file, true);
writeChannel.write(java.nio.ByteBuffer.wrap(data));
writeChannel.closeFinally();
// your blobKey to your data in Google App Engine BlobStore
BlobKey blobKey = fileService.getBlobKey(file);
// THANKS TO BLOBKEY YOU CAN GET FOR EXAMPLE SERVING URL FOR IMAGES
// Get the image serving URL (in https:// format)
String imageUrl =
ImagesServiceFactory.getImagesService().getServingUrl(
ServingUrlOptions.Builder.withBlobKey(blobKey
).secureUrl(true));

Related

View files in j2ee web application using fancybox and google doc viewer

I have a java servlet that serves files from s3. These files can be either image, pdf or doc/docx. I have to implement a feature in my web application to display these files in google doc viewer.
In my case, I am not able to send content so that google doc viewer reads it and displays the file. (when shouldDownload == Binary.YES).
This the code I have that downloads the file from s3 and set it in my bean class -
ApplicantzFileModel document = (ApplicantzFileModel) MongoSelectRogueModel
.selectOneById(ApplicantzFileModel.class, id);
Binary shouldDownload = Binary.valueOf(download);
if (document != null) {
if (shouldDownload == Binary.YES) {
docBean.fileStream = document.downloadFileStream();
docBean.fileName = document.getFileName();
docBean.isFileDownloadResponse = true;
} else {
File file = document.downloadFile();
if (file != null) {
String content = null;
content = FileHandler.read(file);
if (content != null) {
docBean.fileContent = content;
docBean.fileName = document.getFileName();
}
}
}
docBean.actionSuccess = true;
docBean.isFileContentResponse = true;
}
This is the code in my doGet/doPost to serve the response -
if (bean.isFileDownloadResponse) {
OutputStream responseOutputStream;
try {
response.setContentType("application/octet-stream");
response.addHeader("Content-disposition", "inline; filename=" + bean.fileName);
responseOutputStream = response.getOutputStream();
byte[] buf = new byte[4096];
int len = -1;
while ((len = bean.fileStream.read(buf)) != -1) {
responseOutputStream.write(buf, 0, len);
}
responseOutputStream.flush();
responseOutputStream.close();
bean.fileStream.close();
} catch (IOException e1) {
e1.printStackTrace();
}
} else {
response.setContentType("application/msword");
response.addHeader("Content-disposition", "inline; filename=" + bean.fileName);
responseStr = bean.fileContent;
PrintWriter writer = null;
try {
writer = response.getWriter();
} catch (IOException e) {
e.printStackTrace();
}
if (writer != null) {
writer.println(responseStr);
writer.flush();
writer.close();
}
}
And this is the html code in my frontend to open google doc viewer in fancybox -
"<a data-fancybox="" data-type="iframe" data-src="http://docs.google.com/viewer?url=http%3A%2F%2Fsomeserver.com%2Fapplication%2Fdocument%3Faction%3Dget%26id%3Dsomeid%26download%3DYES&embedded=true" href="javascript:void(0);" data-doc-id="someid">My Link</a>"
Or more specifically, google doc viewer url that opens up -
var innerurl = encodeURIComponent('http://someserver.com/application/document?action=get&id='+this.docId+'&download=YES');
this.docUrl = 'http://docs.google.com/viewer?url='+innerurl+'&embedded=true';
I am not able to open the word or pdf document in my fancybox. Can someone please suggest what to do to serve files via Java.

javamail also extract attachments of encapsulated message Content-Type: message/rfc822

I want to extract ALL the attachments of an .eml message which is encapsulated (Content-Type: message/rfc822) in the message InputStream
InputStream is = new FileInputStream(Path);
MimeMessage mime = new MimeMessage(null, is);
private String getAttachments(p) throws
MessagingException, IOException {
if ( p.isMimeType("multipart/*")) {
Multipart multiPart = (Multipart) p.getContent();
int numberOfParts = multiPart.getCount();
for (int partCount = 0; partCount < numberOfParts; partCount++) {
MimeBodyPart part = (MimeBodyPart) multiPart.getBodyPart(partCount);
String disp = part.getDisposition();
if (disp != null && disp.equalsIgnoreCase(Part.ATTACHMENT) {
file_name = part.getFileName();
part.saveFile(Attachments_Folder + "\\" + MailFileName + "_" + file_name);
}
}
}
}
is.close()
Also, when the Content-Type is message/rfc822, the part.getFileName() is null and therefore the saved file has no extension and I don't know how to get this one.
MIME does not require every body part to have a file name. If the part doesn't have a file name and you need one, you'll have to make one up yourself.
Note also that you want to be very careful when using a file name that you get in an email message. It could be something unexpected or malicious, e.g., containing "../../../../../whatever".
I did it by adding a new filename to the included message as an .eml file and a recursion with the included message
import java.util.*;
import javax.activation.DataHandler;
import javax.mail.*;
import javax.mail.internet.*;
import javax.mail.search.*;
import java.io.FileInputStream.*;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeBodyPart;
import javax.mail.Part;
import javax.mail.Multipart;
getAttachments(Path) ;
//function
private String getAttachments(path) throws
MessagingException, IOException {
InputStream is = new FileInputStream(path);
MimeMessage p = new MimeMessage(null, is);
if ( p.isMimeType("multipart/*")) {
// if (contentType.contains("multipart")) {
Multipart multiPart = (Multipart) p.getContent();
int numberOfParts = multiPart.getCount();
for (int partCount = 0; partCount < numberOfParts; partCount++) {
MimeBodyPart part = (MimeBodyPart)multiPart.getBodyPart(partCount);
String disp = part.getDisposition();
if (disp != null && disp.equalsIgnoreCase(Part.ATTACHMENT)) {
file_name = part.contentType == "message/rfc822" ? "message_inclus" + partCount + ".eml" : MimeUtility.decodeText(part.getFileName());
exportedpath = Attachments_Folder + "/" + MailFileName + "_" + file_name;
part.saveFile(exportedpath);
if ( part.contentType == "message/rfc822" ) {
getAttachments(exportedpath)
}
}
}
}
is.close()
return 1
}
Better use org.apache.commons.mail.util.MimeMessageParser.
MimeMessageParser has as method called hasAttachments() which
returns true , if message has an attachments.
Then loop through the all attachments and check for content-type
message/rfc822 from getContentType().
Create new MimeMessage with the DataSource InputStream
final MimeMessage message = new MimeMessage(null,attachment.getInputStream());
Finally you have MimeMessage.
Maven Dependency:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-email</artifactId>
<version>RELEASE</version>
</dependency>
Code Sample:
public void readEmails() throws Exception{
// mail server connection parameters
String host = "host";
String user = "username";
String pwd = "pwd";
// connect to my pop3 inbox
Properties properties = System.getProperties();
Session session = Session.getDefaultInstance(properties);
Store store = session.getStore("pop3");
store.connect(host, user, pwd);
Folder inbox = store.getFolder("INBOX");
inbox.open(Folder.READ_ONLY);
// get the list of inbox messages
Message[] messages = inbox.getMessages();
if (messages.length == 0) System.out.println("No messages found.");
for (int i = 0; i < messages.length; i++) {
// stop after listing ten messages
if (i > 10) {
System.exit(0);
inbox.close(true);
store.close();
}
final MimeMessageParser mimeMessageParser = new MimeMessageParser((MimeMessage) messages[i]);
mimeMessageParser.parse();
if (mimeMessageParser.hasAttachments()) {
List<DataSource> attachmentList = mimeMessageParser.getAttachmentList();
System.out.println("Number of attachments: " +attachmentList.size());
for (DataSource attachment:attachmentList
) {
System.out.println("Name: "+attachment.getName()+" Content Type: "+attachment.getContentType());
if (attachment.getContentType().equals("message/rfc822")) {
final MimeMessage message = new MimeMessage(null,attachment.getInputStream());
System.out.println("Subject of the attached failure Mail:" + message.getSubject());
}
}
}
System.out.println("Message " + (i + 1));
System.out.println("From : " + messages[i].getFrom()[0]);
System.out.println("Subject : " + messages[i].getSubject());
System.out.println("Sent Date : " + messages[i].getSentDate());
System.out.println();
}
inbox.close(true);
store.close();
}

How to insert a youtube video as an attachment to specified timeline item?

Currently attachment takes stream for the content, is it possible to set a youtube video url for the attachment?
Thanks
This is not yet possible with the current version of the API and Glass client. Feel free to file a feature request on our issues tracker.
It is possible to stream a youtube video in the timeline card, here is the C#.Net code. use this name space "YoutubeExtractor".This works fine for me. When getting the youtube video url get the link that comes after you select share.
private static String InsertItem5(MainController controller)
{
string link = "http://youtu.be/9uYKISlL7Vg";
IEnumerable<VideoInfo> videoInfos = DownloadUrlResolver.GetDownloadUrls(link);
VideoInfo video = videoInfos.First(info => info.VideoType == VideoType.Mp4 && info.Resolution == 360);
String vLink = video.DownloadUrl;
TimelineItem critical = new TimelineItem()
{
Text = "Menu Card",
BundleId = "666",
Notification = new NotificationConfig() { Level = "DEFAULT" },
MenuItems = new List<MenuItem>()
{
new MenuItem() {Action = "DELETE"},
}
};
String mediaLink = vLink;
if (!String.IsNullOrEmpty(mediaLink))
{
Stream stream = null;
if (mediaLink.StartsWith("/"))
{
stream = new StreamReader(controller.Server.MapPath(mediaLink)).BaseStream;
}
else
{
HttpWebRequest request = WebRequest.Create(mediaLink) as HttpWebRequest;
request.UseDefaultCredentials = false;
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
byte[] b = null;
using (Stream streamFromWeb = response.GetResponseStream())
using (MemoryStream ms = new MemoryStream())
{
int count = 0;
do
{
byte[] buf = new byte[1024];
count = streamFromWeb.Read(buf, 0, 1024);
ms.Write(buf, 0, count);
} while (streamFromWeb.CanRead && count > 0);
b = ms.ToArray();
stream = new MemoryStream(b);
}
}
controller.Service.Timeline.Insert(critical, stream, "video/mp4").Upload();
}
else
{
controller.Service.Timeline.Insert(critical).Fetch();
}

Uploading a file by Console Application asp.net

i've searched about how to upload files to websites using console applications and i reached some ways, seems like the correct way, but i'm not having sucess with this. So i need some help!
First, the solution that i've founded follows:
class Program
{
static void Main(string[] args)
{
//Program.Test1();
Program.Test3();
Console.ReadLine();
}
public static void Test3()
{
//Set this to dont get an Invalid Request Exception
System.Net.ServicePointManager.Expect100Continue = false;
//Set a real page for this test
string url = "http://www.toledorocket.com/perftest/uploadtest/fileselect.asp";
string[] files = { "C:\\Documents and Settings\\wkurten\\Desktop\\fogao.txt" }; //Put some real file
NameValueCollection nvc = new NameValueCollection();
nvc.Add("FILE1", "fogao.txt");
string boundary = "----------------------------" +
DateTime.Now.Ticks.ToString("x");
HttpWebRequest httpWebRequest2 = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest2.ContentType = "multipart/form-data; boundary=" +
boundary;
httpWebRequest2.Method = "POST";
httpWebRequest2.KeepAlive = true;
httpWebRequest2.Credentials =
System.Net.CredentialCache.DefaultCredentials;
//Is you have an connection with proxy, uncomment and set the values bellow:
/*NetworkCredential localNetworkCredential = new NetworkCredential("user", "pass", "domain");
httpWebRequest2.Proxy = new WebProxy("server:port", false);
httpWebRequest2.Proxy.Credentials = localNetworkCredential;*/
Stream memStream = new System.IO.MemoryStream();
byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" +
boundary + "\r\n");
string formdataTemplate = "\r\n--" + boundary +
"\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}";
foreach (string key in nvc.Keys)
{
string formitem = string.Format(formdataTemplate, key, nvc[key]);
byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
memStream.Write(formitembytes, 0, formitembytes.Length);
}
memStream.Write(boundarybytes, 0, boundarybytes.Length);
string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n Content-Type: application/octet-stream\r\n\r\n";
for (int i = 0; i < files.Length; i++)
{
string header = string.Format(headerTemplate, "file" + i, files[i]);
//string header = string.Format(headerTemplate, "uplTheFile", files[i]);
byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
memStream.Write(headerbytes, 0, headerbytes.Length);
FileStream fileStream = new FileStream(files[i], FileMode.Open,
FileAccess.Read);
byte[] buffer = new byte[1024];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
memStream.Write(buffer, 0, bytesRead);
}
memStream.Write(boundarybytes, 0, boundarybytes.Length);
fileStream.Close();
}
httpWebRequest2.ContentLength = memStream.Length;
Stream requestStream = httpWebRequest2.GetRequestStream();
memStream.Position = 0;
byte[] tempBuffer = new byte[memStream.Length];
memStream.Read(tempBuffer, 0, tempBuffer.Length);
memStream.Close();
requestStream.Write(tempBuffer, 0, tempBuffer.Length);
requestStream.Close();
//Gets the response
WebResponse webResponse2 = httpWebRequest2.GetResponse();
Stream stream2 = webResponse2.GetResponseStream();
StreamReader reader2 = new StreamReader(stream2);
//Retrieve the html from response
string htmlResponse = reader2.ReadToEnd();
webResponse2.Close();
httpWebRequest2 = null;
webResponse2 = null;
}
}
The problem that i'm having with this solution is that when i upload a file and retrieves the WebResponse, the page that i'm getting is the page with the upload form and not the page that appears after upload, that page with the success message.
On the page that i'm trying to upload the file i have this html/form:
<FORM METHOD="POST" ENCTYPE="multipart/form-data" ACTION="uploadstatus.asp">
<INPUT TYPE="FILE" SIZE="40" NAME="FILE1"> <INPUT TYPE=SUBMIT VALUE="Upload!">
</FORM>
When i run my code i just get this same form every time, seems like i'm never posting anything... anyone have an idea of what is happening?

How to save bitmapimage in Isolated storage?

I am developing silverlight web part by using the client object model. I am getting the bitmap image from sharepoint server. Now I want to save this bitmap image in isolated storage. So I am using following code
WriteableBitmap wb = new WriteableBitmap(attachments);
using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream isoStream =
new IsolatedStorageFileStream("abcd1.jpg", FileMode.Create, isoFile))
{
using (StreamWriter sw = new StreamWriter(isoStream))
{
sw.Write(wb.ToByteArray());
}
}
}
Now I am seeing the saved image at location C:\Users\Rent2\AppData\LocalLow\Microsoft\Silverlight\is\vzvpufsm.s4i\m0laonzr.til\1\s\nkhajster01es5wdoyfxd0n5rd2dls3ovyu4wcdig04zjx44hyaaafea\f
When I click on it, it gives me message as "Invalid Image". Can you please tell me how should i write code so that I can see the actual image after saving it in isolated storage ?
private void zipFile()
{
context = Microsoft.SharePoint.Client.ClientContext.Current;
Microsoft.SharePoint.Client.File.OpenBinaryDirect(
context,
#"/TemplateInvoice/" + App.templateFileName + ".xlsx", successFile, FailFile);
}
private void successFile(object sender, OpenBinarySucceededEventArgs args)
{
System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
{
// Obtain the isolated storage for an application.
try
{
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
Stream strm = args.Stream;
using (var isoStream = store.OpenFile(App.templateFileName + ".zip", FileMode.OpenOrCreate))
{
// Read the resource file into a byte array.
bytes = new byte[strm.Length];
int numBytesToRead = (int)strm.Length;
int numBytesRead = 0;
while (numBytesToRead > 0)
{
// Read may return anything from 0 to numBytesToRead.
int n = strm.Read(bytes, numBytesRead, numBytesToRead);
// The end of the file is reached.
if (n == 0)
break;
numBytesRead += n;
numBytesToRead -= n;
}
numBytesToRead = bytes.Length;
// Write the byte array to the IsolatedStorageFileStream.
isoStream.Write(bytes, 0, numBytesToRead);
//isoStream.Dispose();
}
strm.Close();
string path = App.templateFileName + ".zip";
ZipHelp.UnZip(path, System.IO.Path.GetDirectoryName(path), 4096);
replaceFileContent();
string rootDirectory = System.Windows.Browser.HttpUtility.UrlDecode(path);
string fileName = ZipHelp.Zip(rootDirectory.Replace(".zip", ""), invoice);
//string filename = DateTime.Now.Day.ToString() + DateTime.Now.Month.ToString() + DateTime.Now.Year.ToString() + DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString() + "Invoice1.xlsx";
// Read the resource file into a byte array.
using (var stream = store.OpenFile(fileName, FileMode.Open))
{
bytes = new byte[stream.Length];
int numBytesToRead = (int)stream.Length;
int numBytesRead = 0;
while (numBytesToRead > 0)
{
// Read may return anything from 0 to numBytesToRead.
int n = stream.Read(bytes, numBytesRead, numBytesToRead);
// The end of the file is reached.
if (n == 0)
break;
numBytesRead += n;
numBytesToRead -= n;
}
InvoiceTemplete invoiceTemplate = new InvoiceTemplete(fileName, bytes, SetMessage);
invoiceTemplate.AddDocument(invoiceTemplate);
}
}
//mark rows as billed
foreach (var item in PrivatePayList)
{
MedwaiverViewModel MedwaiverViewModelObj = new MedwaiverViewModel();
MedwaiverViewModelObj.ChangeBillingStatus(item.ListItemId, "Billed");
if (MedwaiverTimeLogList != null)
{
MedwaiverTimeLogList.Remove(item);
}
if (ClientSpecificTimeLogList != null)
{
ClientSpecificTimeLogList.Remove(item);
}
if (rangeBoundTimeLogListForDate != null)
{
rangeBoundTimeLogListForDate.Remove(item);
}
if (vRangeBoundTimeLogListForDateAndClient != null)
{
vRangeBoundTimeLogListForDateAndClient.Remove(item);
}
}
}
catch (IsolatedStorageException isx)
{
MessageBox.Show(isx.Message);
}
});
}
private void FailFile(object sender, OpenBinaryFailedEventArgs e)
{
System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("Fail");
});
}
//The following class zip and unzip the file
class ZipHelp
{
static List<string> folderPathList = new List<string>();
public static string Zip(string rootDirectory, string fileName)
{
byte[] buffer;
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
IsolatedStorageFileStream zipFileStream = store.CreateFile(fileName + ".xlsx");
ZipOutputStream zipOutStream = new ZipOutputStream(zipFileStream);
zipOutStream.UseZip64 = UseZip64.Off;
//zipOutStream.CanPatchEntries
foreach (var item in folderPathList)
{
string entryName = "";
buffer = new byte[4096];
if (item.Substring(0,1) == #"/")
{
//removes leading /
entryName = item.Substring(1);
}
else
{
entryName = item;
}
ZipEntry entry = new ZipEntry(entryName);
//entry.CompressionMethod = CompressionMethod.Deflated;
//entry.
entry.IsZip64Forced();
//entry.IsDirectory
zipOutStream.PutNextEntry(entry);
using (IsolatedStorageFileStream stream = store.OpenFile(rootDirectory + #"\" + item, FileMode.Open))
{
int size;
do
{
size = stream.Read(buffer, 0, buffer.Length);
zipOutStream.Write(buffer, 0, size);
} while (size > 0);
stream.Close();
}
}
zipOutStream.Close();
zipFileStream.Close();
}
return fileName + ".xlsx";
//string[] directories = GetLocationTypes();
//zip();
//string[] filenames = Directory.GetFiles(directories);
//using (var store = IsolatedStorageFile.GetUserStoreForApplication())
//{
// using (var isoStream = store.OpenFile("#" + rootDirectory, FileMode.OpenOrCreate))
// {
// //foreach(string dir in
// }
//}
}
private static string[] GetLocationTypes()
{
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
return store.GetDirectoryNames();
}
}
/// <summary>
/// UnZip a file
/// </summary>
/// <param name="SrcFile">source file path</param>
/// <param name="DstFile">unzipped file path</param>
/// <param name="BufferSize">buffer to use</param>
public static void UnZip(string SrcFile, string DstFile, int BufferSize)
{
folderPathList.Clear();
IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication();
FileStream fileStreamIn = store.OpenFile(SrcFile, FileMode.Open, FileAccess.Read);
ZipInputStream zipInStream = new ZipInputStream(fileStreamIn);
string rootDirectory = System.Windows.Browser.HttpUtility.UrlDecode(SrcFile);
rootDirectory = rootDirectory.Replace(".zip", "");
store.CreateDirectory(rootDirectory);
while (true)
{
ZipEntry entry = zipInStream.GetNextEntry();
if (entry == null)
break;
if (entry.Name.Contains("/"))
{
string[] folders = entry.Name.Split('/');
string lastElement = folders[folders.Length - 1];
var folderList = new List<string>(folders);
folderList.RemoveAt(folders.Length - 1);
folders = folderList.ToArray();
string folderPath = "";
foreach (string str in folders)
{
folderPath = folderPath + "/" + str;
if (!store.DirectoryExists(rootDirectory + "/" + folderPath))
{
store.CreateDirectory(rootDirectory + "/" + folderPath);
}
}
folderPath = folderPath + "/" + lastElement;
writeToFile(BufferSize, fileStreamIn, zipInStream, rootDirectory, folderPath);
}
else
{
writeToFile(BufferSize, fileStreamIn, zipInStream, rootDirectory, entry.Name);
}
}
zipInStream.Close();
fileStreamIn.Close();
}
private static void writeToFile(int BufferSize, FileStream fileStreamIn, ZipInputStream zipInStream, string rootDirectory, string folderPath)
{
IsolatedStorageFile store1 = IsolatedStorageFile.GetUserStoreForApplication();
FileStream fileStreamOut = store1.OpenFile(rootDirectory + "/" + folderPath, FileMode.Create, FileAccess.Write);
folderPathList.Add(folderPath);
int size;
byte[] buffer = new byte[BufferSize];
do
{
size = zipInStream.Read(buffer, 0, buffer.Length);
fileStreamOut.Write(buffer, 0, size);
} while (size > 0);
fileStreamOut.Close();
}
}
I can think of two viable options here.
In your code above, save off the Pixels array of the WriteableBitmap. Then to restore it, you would create a WriteableBitmap of the appropriate size and the set the Pixels array to the stored data.
-or-
Use a HttpWebRequest or WebClient request to get the raw image stream and save that to IsolatedStorage.
There are pros and cons to each of these, in the first case the data is uncompressed and will take up more space in isolated storage and you would not be able to open the image from disk outside of Silverlight, similar to the issue you had above. For the second option you can run into cross domain issues if the images are on a different server than your Silverlight XAP file and it's also a bit more complex to implement.
The basic problem is that you're storing the decoded RGBA pixels array as a JPEG file - but they're not the same. Your code is basically correct: you just can't use this method to store it as a JPEG file. But if you happen to know that the image is, say, 800x600, you could create an 800x600 WriteableBitmap, and then set the Pixels property to the retrieved stream's byte array. Or if you don't know the dimensions when you're retrieving it, you could store the dimensions as the first two integers in the stream (before you write the pixels to the stream), and read out the dimensions when you're reading the file. You'd effectively be creating your own very simplistic .bmp format.

Resources