I want to access a folder other than root folders in UWP. The user will select the file with a file picker and then this file will be used for software update.
I am able to provide file selection as below. Then when I read this file, I get the error that I do not have permission to access it.
var picker = new FileOpenPicker();
picker.ViewMode = PickerViewMode.Thumbnail;
picker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
picker.FileTypeFilter.Add(".bin");
file = await picker.PickSingleFileAsync();
StorageFolder folder = await StorageFolder.GetFolderFromPathAsync(file.Path);
StorageFile storageFile = await storageFolder.GetFileAsync(file.Name);
var fileStream = System.IO.File.Open(storageFile.Path, FileMode.Open);
If I manually copy the folder to the root folder and it works fine with the code below.
StorageFolder storageFolder = ApplicationData.Current.LocalFolder;
StorageFile storageFile = await storageFolder.GetFileAsync(file.Name);
var fileStream = System.IO.File.Open(storageFile.Path, FileMode.Open);
Solution for me in two ways. The first is to copy files from the outside to the root folder, the second way is to eliminate the access permission problem.Since it is a constantly changing file, I cannot import it into the project.
Uwp has strong file access restriction, File.open is not uwp api, it can only access two location, which are Application install directory and Application data locations, so your code works well when you copy this file to Application data location. Therefore, I suggest you could use StorageFile.OpenAsync method instead of File.open() to get the stream.
Related
I have a custom form using a "managed_file" which uploads to temp folder. Programmatically, I then load that file and move it to its permanent storage (overwriting any existing file with the* name) e.g.
// Upload file
$upfile = $this->entityTypeManager->getStorage('file')->load($fid);
// Source and destination
$sourceUri = $this->fileSystem->realpath($upfile->getFileUri());
$destinationUri = $this->fileSystem->realpath(\Drupal::config('system.file')->get('default_scheme') . "://") . '/x/y/z/XYZ_NEW.pdf';
// Move and overwrite
$this->fileSystem->move($sourceUri, $destinationUri, FileSystemInterface::EXISTS_REPLACE);
All of this works (i.e. the file physically is moved into the correct place with correct name); however, the file displayed in the listings (i.e. /admin/content/files) still shows the incorrect temporary folder as the URI.
Basically the file in the listings page seems to be showing the original filepath and name* of a previously successfully moved* file.
If I load this file with incorrect URI, i.e. using the incorrect temp path, the data loads, but then will not have a file info (as it doesn't exist. Also clicking the filename by browser under listings will show page not found and the URL showing the old URL i.e. /system/temporary?file=XYZ.pdf).
If I load this file by correct URI, i.e. using the correct destination path, file not found - same if I go to the path directly in the browser.
It appears the managed file doesn't know it was moved. How to resolve this bug?
The docs for FileSystem::move say "Moves a file to a new location without database changes or hook invocation."
So you are going to need to update the file entity with the new values..
Try this, untested:
// Upload file
$upfile = $this->entityTypeManager->getStorage('file')->load($fid);
// Source and destination
$sourceUri = $this->fileSystem->realpath($upfile->getFileUri());
$destinationUri = $this->fileSystem->realpath(\Drupal::config('system.file')->get('default_scheme') . "://") . '/x/y/z/XYZ_NEW.pdf';
// Move and overwrite
$newFileName = $this->fileSystem->move($sourceUri, $destinationUri, FileSystemInterface::EXISTS_REPLACE);
// Set the new file path on the file entity.
$upfile->setFileUri($newFileName);
// Set the file to permanent if needed.
$upfile->setPermanent();
// Save entity with changes.
$upfile->save();
I did not test this though.
You can check the functions on the file entity in the docs here
It turns out the class based methods do not update the database
https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21File%21FileSystem.php/function/FileSystem%3A%3Amove/8.9.x
The procedural version does
https://api.drupal.org/api/drupal/core%21modules%21file%21file.module/function/file_move/8.9.x
I have one file which is stored at D:/home/abc.pdf locally.
I have to read this file using AngularJs
var path="D:/home/abc.pdf";
var doc = document.createElement("a");
doc.href = path;
doc.download = path;
doc.click();
window.URL.revokeObjectURL(path);
I am not able to download this file.Giving error like Failed-Network error
That is impossible since local files are protected. Else you would be able to manipulate the hard drive as you wanted just by running a local HTML page.
So : if you want to get a file from the computer's hard drive, you have to use an <input> field and ask the user to upload the file using it.
I'm creating a project of a school. I want to show the uploaded stuff by teachers to students.
But I also need to save the file in the folder which is named as faculty name. Student will be able to browse the main directory and after that he can go in the particular faculties folder.
How can I do it? Any suggestions will be appreciated.
For file upload I would start with example like in this answer. Moving files from temporary folder could be easily done by the file uploading action.
For browsing files in your case I would create an action that is able to navigate to the folder where the files are and get a list of files from that folder. Something like this
String file = application.getRealPath("/upload");
File f = new File(file);
String [] fileNames = f.list();
File [] fileObjects= f.listFiles();
for (int i = 0; i < fileObjects.length; i++) {
if(!fileObjects[i].isDirectory()){
String fname = file+fileNames[i];
out.println(fileNames[i]);
}
}
Then map this files to the JSP as links. When that link is clicked you can retrieve the actual path on the server when action is executed. What to do with the data, of course you can return stream result from the action that is used for streaming to the client browser. You can use docs examples from the Struts site or like in this example.
To navigate to the folder use parameters in GET request, that will be used to store current directory in session. You can change it if a user change the current directory from the view layer.
In my app I download several kinds of files (like audio,video,pdf,powerpoint,ect) .
So I receive those data from the webserver as byte[] objects.
So I would like to open them with a video player or a pdfreader now.
What am I supposed to do?
I tried this code but I guess it only works if ou have a file stored in your project's folder(that's not my case)...doesn't it?
// Access the file.
StorageFile pdfFile = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync("FileToRead.pdf");
// Launch the pdf file.
await Windows.System.Launcher.LaunchFileAsync(pdfFile);
Use this to get a file from Isolated Storage
var file = await ApplicationData.Current.LocalFolder.GetFileAsync(filename);
I am attempting to use Google Picker to upload files to a specific folder in Google Drive. Everything works fine when I am just uploading to the root folder, but even after specifying the parent folder as shown in my code below, the files still go to the root folder, not the folder I am specifying. I am certain the folderID is correct, as I am using the same ID elsewhere to create textiles in my GAE app, and place them in subfolders. My code is below:
function createPicker() {
// Create a view to search images.
var view = new google.picker.View(google.picker.ViewId.DOCS);
view.setMimeTypes('image/png,image/jpeg');
// Use DocsUploadView to upload documents to Google Drive.
var uploadView = new google.picker.DocsUploadView().setParent('THE Parent folder ID');
var picker = new google.picker.PickerBuilder().
addView(view).
addView(uploadView).
setAppId("pressomatic").
setCallback(pickerCallback).
build();
picker.setVisible(true);
}
You have to add:
enableFeature(google.picker.Feature.MULTISELECT_ENABLED)
In your case it becomes:
var picker = new google.picker.PickerBuilder().
enableFeature(google.picker.Feature.MULTISELECT_ENABLED).
addView(view).
addView(uploadView).
setAppId("pressomatic").
setCallback(pickerCallback).
build();
picker.setVisible(true);
}
This is a bug documented in the Picker API Forum: https://groups.google.com/forum/#!topic/Google-Picker-API/xaHcET7JYLw
You have to add:
.enableFeature(google.picker.Feature.MULTISELECT_ENABLED)
In your case it becomes:
var picker = new google.picker.PickerBuilder()
.enableFeature(google.picker.Feature.MULTISELECT_ENABLED)
.addView(view)
.addView(uploadView)
.setAppId("pressomatic")
.setCallback(pickerCallback)
.build();
Hope this helps.