I am downloading a file from a url and saving it to a directory on my phone.
the path is: /private/var/mobile/Applications/17E4F0B0-0781-4259-B39D-37057D44B778/Documents/samplefile.txt
However, when i debug the file is created and downloaded. But, when i ad-hoc it and run the file. samplefile.txt is created but it's blank.
Code:
String directory = Environment.GetFolderPath (Environment.SpecialFolder.MyDocuments);
var filename = Path.Combine (directory, "samplefile.txt");
if (!File.Exists (filename)) {
File.Create (filename);
var webClient = new WebClient ();
webClient.DownloadStringCompleted += (s, e) => {
var text = e.Result; // get the downloaded text
File.WriteAllText (filename, text);
};
var url = new Uri (/**myURL**/);
webClient.Encoding = Encoding.UTF8;
webClient.DownloadStringAsync (url);
I modified your sample slightly and the following works for me.
The StreamReader is only there just to re-read in the contents of the file to confirm that its the same contents in the file as that of the downloaded file:-
If you put a breakpoint there also you can manually inspect same contents as downloaded.
string directory = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
var filename = Path.Combine(directory, "samplefile.txt");
if (!File.Exists(filename))
{
var webClient = new WebClient();
webClient.DownloadStringCompleted += (s, e) =>
{
// Write contents of downloaded file to device:-
var text = e.Result; // get the downloaded text
StreamWriter sw = new StreamWriter(filename);
sw.Write(text);
sw.Flush();
sw.Close();
sw = null;
// Read in contents from device and validate same as downloaded:-
StreamReader sr = new StreamReader(filename);
string strFileContentsOnDevice = sr.ReadToEnd();
System.Diagnostics.Debug.Assert(strFileContentsOnDevice == text);
};
var url = new Uri("**url here**, UriKind.Absolute);
webClient.Encoding = Encoding.UTF8;
webClient.DownloadStringAsync(url);
}
Related
I am trying to create a Word file and download the created file in clients browser.
The creation part seems to work fine and I can open the file manually from its Folder.
But the downloaded file in browser does not open correctly and produces an error
"The file is corrupt and cannot be opened"
I am using the code from here
Microsoft instructions for downloading a file in Blazor
My code seems like this
private async Task CreateAndDownloadWordFile()
{
var destination = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
var fileName = destination + "\\test12.docx";
//SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(destination, SpreadsheetDocumentType.Workbook);
using (WordprocessingDocument doc = WordprocessingDocument.Create
(fileName, DocumentFormat.OpenXml.WordprocessingDocumentType.Document))
{
// Add a main document part.
MainDocumentPart mainPart = doc.AddMainDocumentPart();
// Create the document structure and add some text.
mainPart.Document = new Document();
Body body = mainPart.Document.AppendChild(new Body());
Paragraph para = body.AppendChild(new Paragraph());
Run run = para.AppendChild(new Run());
// String msg contains the text, "Hello, Word!"
run.AppendChild(new Text("New text in document"));
}
var fileStream = GetFileStream();
using var streamRef = new DotNetStreamReference(stream: fileStream);
await JS.InvokeVoidAsync("downloadFileFromStream", fileName, streamRef);
}
private Stream GetFileStream()
{
var randomBinaryData = new byte[50 * 1024];
var fileStream = new MemoryStream(randomBinaryData);
return fileStream;
}
And I use this Javascript code
async function downloadFileFromStream(fileName, contentStreamReference) {
const arrayBuffer = await contentStreamReference.arrayBuffer();
const blob = new Blob([arrayBuffer]);
const url = URL.createObjectURL(blob);
triggerFileDownload(fileName, url);
URL.revokeObjectURL(url);
}
function triggerFileDownload(fileName, url) {
const anchorElement = document.createElement('a');
anchorElement.href = url;
anchorElement.download = fileName ?? '';
anchorElement.click();
anchorElement.remove();
}
Any ideas?
But the downloaded file in browser does not open correctly
That is probably because you
First create a Word document
And then download var randomBinaryData = new byte[50 * 1024];
the downloaded file in browser
Check those. Are they exactly 50 * 1024 bytes ?
--
Also, you shouldn't pass the full C:\... path to the download funtion.
var fileStream = File.OpenRead(filename);
using var streamRef = new DotNetStreamReference(stream: fileStream);
//await JS.InvokeVoidAsync("downloadFileFromStream", fileName, streamRef);
await JS.InvokeVoidAsync("downloadFileFromStream", "suggestedName", streamRef);
Where can I find code and instruction on how to allow users to upload files with Google Form without login?
I searched all over here and couldn't find any information.
https://developers.google.com/apps-script/reference
Thanks in advance.
The user will be uploading the files to your drive. So, google needs to verify the user. If there is no verification, someone can fill your drive in no time.
It is for your safety to know who has uploaded, so, login is must.
There's a workaround, I'm in a hurry to write the code now, but if you're interested let me know and I'll edit later.
Basically, you set up a web app with apps script, then you setup a custom HTML form, you'll have to manually collect the file, convert is to base64 then json, then when you catch it in apps script you reverse the process and save it wherever you want in your drive.
Since the user will be executing the script as you, there's no verification required
/*
These functions basically go through a file array and reads the files first as binary string (in second function), then converts the files to base64 string (func 1) before stringifying the files (after putting their base64 content into an object with other metadata attached; mime, name e.t.c);
You pass this stringified object into the body part of fetch(request,{body:"stringified object goes here"})
see next code block for how to read in apps script and save the files to google drive
N.B. The body data will be available under doPost(e){e.postData.contents}
*/
async function bundleFilesForUpload(){
let filesDataObj = [];
let copy = {fileInfo:{"ogname":"","meme":""},fileData:""};
for(let i = 0 ; i < counters.localVar.counters.filesForUploadArr.length ; i++){
let tempObj = JSON.parse(JSON.stringify(copy));
let file = counters.localVar.counters.filesForUploadArr[i];
tempObj.fileInfo.ogname = file.name;
tempObj.fileInfo.meme = file.type;
tempObj.fileData = await readFile(file).then((file)=>{
file = btoa(file);
return file;
}).then((file)=>{
return file;
})
filesDataObj.push(tempObj);
}
return filesDataObj;
}
async function readFile (file){
const toBinaryString = file => new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsBinaryString(file);
reader.onload = () => resolve(reader.result);
reader.onerror = error => reject(error);
});
let parsedFile = null;
parsedFile = await toBinaryString(file);
return parsedFile;
}
/*From doPost downward, we read the file Array convert the base64 to blob and make a file in google drive using the blob and metadata we have, you may also see some sheet code, I'm using sheet as db for this */
//in buit function doPost in Code.gs
doPost(e){
const myDataObj = JSON.parse(e.postData.contents);
mainFileFunc(myDataObj.params[0].dataObj.images);
//the actual object structure might look different from yours, console log around
}
function mainFileFunc(fileArr) {
let myArrObj = [{"madeit":"toFileF"}];
let copy = JSON.parse(JSON.stringify(myArrObj[0]));
//sheet.getRange("A1").setValue(JSON.stringify(fileArr.length));
for(let i=0 ; i < fileArr.length ; i++){
myArrObj.push(copy);
let blob = doFileStuff(fileArr[i].data,fileArr[i].info[0].mime,fileArr[i].id);
myArrObj[i] = uploadFileOne(blob,fileArr[i].id);
myArrObj[i].mime = fileArr[i].info[0].mime;
myArrObj[i].realName = fileArr[i].name;
// sheet.getRange("A"+(i+1)).setValue(myArrObj[i].name);
// sheet.getRange("B"+(i+1)).setValue(myArrObj[i].url);
// sheet.getRange("C"+(i+1)).setValue(myArrObj[i].mime);
// sheet.getRange("D"+(i+1)).setValue(myArrObj[i].size);
}
return myArrObj;
}
function doFileStuff(filedata,filetype,filename){
var data = Utilities.base64Decode(filedata, Utilities.Charset.UTF_8);
var blob = Utilities.newBlob(data,filetype,filename);
return blob;
}
function uploadFileOne(data,filename) {
let myObj = {}
myObj["name"] = "";
myObj["realName"] = "Story_Picture";
myObj["url"] = "";
myObj["mime"] = "";
myObj["size"] = "";
myObj["thumb"] = "nonety";
var folders = DriveApp.getFoldersByName("LadhaWeb");
while (folders.hasNext()) {
var folder = folders.next();
folder.createFile(data);
}
var files = DriveApp.getFilesByName(filename);
while (files.hasNext()) {
var file = files.next();
myObj.name = file.getName();
myObj.url = file.getUrl();
myObj.mime = file.getMimeType();
myObj.size = file.getSize();
}
return myObj;
}
You can view the full frontend code for this project here and the backend here.
Hope this helps someone.
This is my piece of code:
Metadata metadata = new Metadata();
BodyContentHandler handler = new BodyContentHandler();
FileInputStream inputstream = new FileInputStream(new File(
"resources/bed_bath_beyond.gif"));
ParseContext parseContext = new ParseContext();
Parser parser = new AutoDetectParser();
parseContext.set(Parser.class, parser);
parser.parse(inputstream , handler, metadata, parseContext);
XHTMLContentHandler xhandler=new XHTMLContentHandler(handler, metadata);
String text = xhandler.toString();
System.out.println("Contents of the document:" + text);
Above code gives OUTPUT:
Contents of the document:
I am not getting content of the file in output.
Please help.
I want to download a file and save it into my app folder. I have to download different files with different formats, but only one each time.
I've read that I have to use HttpUtils, but sample codes are to difficult for me (I'm too noob).
Can anyone upload any sample code?? Thanks!!
This should point you in the right direction:
URL u = new URL(urlString);
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
File file = new File(outputDirectoryFile, outputFileName);
OutputStream out = new FileOutputStream(file);
InputStream in = c.getInputStream();
byte[] buffer = new byte[4096];
while ( (int len1 = in.read(buffer)) > 0 ) {
out.write(buffer,0, len1);
}
in.close();
out.close();
c.disconnect();
Remember, you should never perform operations like this on the default UI tread. It could prompt the user to force close your app. Read more here:
http://developer.android.com/resources/articles/painless-threading.html
This is how I finally do:
imgurl = "http://dl.dropbox.com/u/25045/file.jpg"
HttpUtils.CallbackActivity = "myactivity" 'Current activity name.
HttpUtils.CallbackJobDoneSub = "JobDone"
HttpUtils.Download("Job1", imgurl)
Dim out As OutputStream
out = File.OpenOutput(File.DirInternal, "file.jpg", True)
File.Copy2(HttpUtils.GetInputStream(imgurl), out)
out.Close
I have written
List<Attachment> lstAttachment = new List<Attachment>();
//Check if any error file is present in which case it needs to be send
if (new FileInfo(Path.Combine(errorFolder, errorFileName)).Exists)
{
Attachment unprocessedFile = new Attachment(Path.Combine(errorFolder, errorFileName));
lstAttachment.Add(unprocessedFile);
}
//Check if any processed file is present in which case it needs to be send
if (new FileInfo(Path.Combine(outputFolder, outputFileName)).Exists)
{
Attachment processedFile = new Attachment(Path.Combine(outputFolder, outputFileName));
lstAttachment.Add(processedFile);
}
Working fine and is giving the expected output.
Basically I am attaching the file to the list based on whether the file is present or not.
I am looking for any other elegant solution than the one I have written.
Reason: Want to learn differnt ways of representing the same program.
I am using C#3.0
Thanks.
Is it looks better?
...
var lstAttachment = new List<Attachment>();
string errorPath = Path.Combine(errorFolder, errorFileName);
string outputPath = Path.Combine(outputFolder, outputFileName);
AddAttachmentToCollection(lstAttachment, errorPath);
AddAttachmentToCollection(lstAttachment, outputPath);
...
public static void AddAttachmentToCollection(ICollection<Attachment> collection, string filePath)
{
if (File.Exists(filePath))
{
var attachment = new Attachment(filePath);
collection.Add(attachment);
}
}
How about a little LINQ?
var filenames = new List<string>()
{
Path.Combine(errorFolder, errorFilename),
Path.Combine(outputFolder, outputFilename)
};
var attachments = filenames.Where(f => File.Exists(f))
.Select(f => new Attachment(f));