Xamrin Forms: How to read the details of a file stored in device's external storage? - file

I have implemented creating a folder and file in the device's external storage and writing data into that file using this thread.
Now I am trying to get the details of the file. For that, I have added a new function in the interface like below.
//Interface
public interface IAccessFile
{
void CreateFile(string text);
Java.IO.File GetFileDetails();
}
//Android implementation
public Java.IO.File GetFileDetails()
{
string rootPath = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
var filePathDir = Path.Combine(rootPath, "StockPDT");
if (File.Exists(filePathDir))
{
string filePath = Path.Combine(filePathDir, "STOCK.TXT");
Java.IO.File file = new Java.IO.File(filePath);
return file;
}
else
{
return null;
}
}
But the problem is with the interface function part, getting below error":
The type or namespace name 'Java' could not be found (are you missing a using directive or an assembly reference?)
Screenshot:
If I return the file from the android part like above, it is easy to get the file details in the portable project. Instead of File, I try to return the file path, but it is empty. Is there any other way to get the file details other than this?

As per the notes in question, I tried to fetch the file details using its path.
Reference: https://learn.microsoft.com/en-us/answers/questions/319908/xamrin-forms-how-to-read-the-details-of-a-file-sto.html
//Interface
public interface IAccessFile
{
string GetFileDetails();
}
//Android implementation
public string GetFileDetails()
{
string rootPath = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
var filePathDir = Path.Combine(rootPath, "StockPDT");
if (!File.Exists(filePathDir))
{
Directory.CreateDirectory(filePathDir);
}
string filePath = Path.Combine(filePathDir, "STOCK.TXT");
return filePath;
}
//Main Project:
string path = DependencyService.Get<IAccessFile>().GetFileDetails();
string fileDetails = File.ReadAllText(path);

Related

How do I save multiple files in a package folder from a SwiftUI Document Based App?

I'm developing a SwiftUI document-based app that contains some easily serializable data plus multiple images. I'd like to save the document as a package (i.e, a folder) with one file containing the easily serialized data and a subfolder containing the images as separate files. My package directory should look something like this:
<UserChosenName.pspkg>/. // directory package containing my document data and images
PhraseSet.dat // regular file with serialized data from snapshot
Images/ // subdirectory for images (populated directly from my app as needed)
Image0.png
Image1.png
....
I've created a FileWrapper subclass that sets up the directory structure and adds the serialized snapshot appropriately but when I run the app in an iOS simulator and click on "+" to create a new document the app runs through the PkgFileWrapper init() and write() without error but returns to the browser window without apparently creating anything. I have declared that the Exported and Imported Type Identifiers conform to "com.apple.package". Can anyone suggest a way to get this working?
The PkgFileWrapper class looks like this:
class PkgFileWrapper: FileWrapper {
var snapshot: Data
init(withSnapshot: Data) {
self.snapshot = withSnapshot
let sWrapper = FileWrapper(regularFileWithContents: snapshot)
let dWrapper = FileWrapper(directoryWithFileWrappers: [:])
super.init(directoryWithFileWrappers: ["PhraseSet.dat" : sWrapper,
"Images" : dWrapper ])
// NOTE: Writing of images is done outside
// of the ReferenceFileDocument functionality.
}
override func write(to: URL,
options: FileWrapper.WritingOptions,
originalContentsURL: URL?) throws {
try super.write(to: to, options: options,
originalContentsURL: originalContentsURL)
}
required init?(coder inCoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
The solution is to not override PkgFileWrapper.write(...). If the directory structure is set up correctly in the init(...) then the files and directories will be created automatically. The overridden write(...) function above has now been corrected.
If you want to write an image to the Images subdirectory, you could do something like the following:
func addImage(image: UIImage, name: String) {
let imageData = image.pngData()!
imageDirWrapper.addRegularFile(withContents: imageData,
preferredFilename: name)
}
The value of imageDirWrapper is the directory wrapper corresponding to the directory that holds your images, as created in PkgFileWrapper.init() above. A key concept you need to keep in mind here is that the "write" function will get called automatically at the appropriate time - you don't explicitly write out your image data. The ReferenceFileDocument class will arrange for that and will also arrange for your app to be passed the appropriate URL for setting up your file wrappers.
The imageDirWrapper variable is set in the required init(...) for the ReferenceFileDocument protocol:
required init(configuration: ReadConfiguration) throws {
phraseSet = PhraseSet()
if configuration.file.isDirectory {
if let subdir = configuration.file.fileWrappers {
// first load in the phraseSet
for (name, wrapper) in subdir {
if name == PkgFileWrapper.phraseSetFileName {
if let data = wrapper.regularFileContents {
phraseSet = try PhraseSet(json: data)
}
}
}
// next load in the images and put them into the phrases.
for (name, wrapper) in subdir {
if name == PkgFileWrapper.imageDirectoryName {
if let imageDir = wrapper.fileWrappers {
imageDirWrapper = wrapper
for (iName, iWrapper) in imageDir {
print("image file: \(iName)")
if let d = iWrapper.regularFileContents {
for p in phraseSet.phrases {
if p.imageName == iName {
// TBD: downsample
var uiD = ImageData(data: d)
if doDownSample {
uiD.uiimageData = downsample(data: d,
to: imageSize)
} else {
_ = uiD.getUIImage()
}
images[iName] = uiD
}
}
}
}
}
}
}
}
} else {
throw CocoaError(.fileReadCorruptFile)
}
You can see here how imageDirWrapper is set by looking through the passed-in directory's subdirectories for the image directory name. Also some bonus code: it first looks through the passed-in directory for the data file and loads it in; then it looks for the image directory and processes it.

Is there a way in selenium to upload the last downloaded file with dynamic name?

The problem I am facing is I have a file which is having a dynamic number at the last.
For example: Tax_subscription_124.pdf which changes everytime.
Can I upload this particular file as currently I am downloading it in a particular location but not able to upload the same due to dynamic name?
The following code returns the last modified file or folder:
public static File getLastModified(String directoryFilePath)
{
File directory = new File(directoryFilePath);
File[] files = directory.listFiles(File::isFile);
long lastModifiedTime = Long.MIN_VALUE;
File chosenFile = null;
if (files != null)
{
for (File file : files)
{
if (file.lastModified() > lastModifiedTime)
{
chosenFile = file;
lastModifiedTime = file.lastModified();
}
}
}
return chosenFile;
}
Note that it required Java 8 or newer due to the lambda expression.
After that
WebElement fileInput = driver.findElement(By.name("uploadfile"));
fileInput.sendKeys(chosenFile);

StackOverflowError while reading file from reactive GridFS

I have a problem with the ReactiveGridFsTemplate. I am trying to read a GridFS file written with the old GridFS (com.mongodb.gridfs) instead of the new GridFS (com.mongodb.client.gridfs.model.GridFS) with an UUID as an ID instead of the ObjectId. Reading the GridFS file metainfo goes fine, but as soon as I want to get the ReactiveGridFsResource it blows with a nice new MongoGridFSException("Custom id type used for this GridFS file").
The culprit is the code below from ReactiveGridFsTemplate which calls the getObjectId() instead of the getId(). Should it call this method or can that be rewritten to the getId() method?
public Mono<ReactiveGridFsResource> getResource(GridFSFile file) {
Assert.notNull(file, "GridFSFile must not be null!");
return Mono.fromSupplier(() -> {
GridFSDownloadStream stream = this.getGridFs().openDownloadStream(file.getObjectId());
return new ReactiveGridFsResource(file, BinaryStreamAdapters.toPublisher(stream, this.dataBufferFactory));
});
}
I hacked the ReactiveGridFsTemplate to use getId() instead of getObjectId() but now it gives me a stackoverflow exception. Can someone tell me what I'm doing wrong?
ReactiveGridFsTemplate reactiveGridFsTemplate = new ReactiveGridFsTemplate(mongoDbDFactory, operations.getConverter(), "nl.loxia.collectie.buitenlandbladen.dgn", 1024) {
public Mono<ReactiveGridFsResource> getResource(GridFSFile file) {
Assert.notNull(file, "GridFSFile must not be null!");
return Mono.fromSupplier(() -> {
GridFSDownloadStream stream = this.getGridFs().openDownloadStream(file.getId());
return new ReactiveGridFsResource(file, BinaryStreamAdapters.toPublisher(stream, this.dataBufferFactory));
});
}
};
var q = Query.query((Criteria.where("_id").is("5449d9e3-7f6d-47b7-957d-056842f190f7")));
List<DataBuffer> block = reactiveGridFsTemplate
.findOne(q)
.flatMap(reactiveGridFsTemplate::getResource)
.flux()
.flatMap(ReactiveGridFsResource::getDownloadStream)
.collectList()
.block();
The stacktrace: https://gist.github.com/nickstolwijk/fa77681572db1d91941d85f6c845f2f4
Also, this code hangs due to the stackoverflow exception. Is that correct?

Eclipse PDE: Get full path of an external file open in Workbench

I am writing an Eclipse Plugin which requires me to get full path of any kind of file open in the Workspace.
I am able to get full path of any file which is part of any Eclipse project. Code to get open/active editor file from workspace.
public static String getActiveFilename(IWorkbenchWindow window) {
IWorkbenchPage activePage = window.getActivePage();
IEditorInput input = activePage.getActiveEditor().getEditorInput();
String name = activePage.getActiveEditor().getEditorInput().getName();
PluginUtils.log(activePage.getActiveEditor().getClass() +" Editor.");
IPath path = input instanceof FileEditorInput ? ((FileEditorInput) input).getPath() : null;
if (path != null) {
return path.toPortableString();
}
return name;
}
However, if any file is drag-dropped in Workspace or opened using File -> Open File. For instance, I opened a file from /Users/mac/log.txt from File -> Open File. My plugin is not able to find location of this file.
After couple of days search, I found the answer by looking at the source code of Eclipse IDE.
In IDE.class, Eclipse tries to find a suitable editor input depending on the workspace file or an external file. Eclipse handles files in workspace using FileEditorInput and external files using FileStoreEditorInput. Code snippet below:
/**
* Create the Editor Input appropriate for the given <code>IFileStore</code>.
* The result is a normal file editor input if the file exists in the
* workspace and, if not, we create a wrapper capable of managing an
* 'external' file using its <code>IFileStore</code>.
*
* #param fileStore
* The file store to provide the editor input for
* #return The editor input associated with the given file store
* #since 3.3
*/
private static IEditorInput getEditorInput(IFileStore fileStore) {
IFile workspaceFile = getWorkspaceFile(fileStore);
if (workspaceFile != null)
return new FileEditorInput(workspaceFile);
return new FileStoreEditorInput(fileStore);
}
I have modified the code posted in the question to handle both files in Workspace and external file.
public static String getActiveEditorFilepath(IWorkbenchWindow window) {
IWorkbenchPage activePage = window.getActivePage();
IEditorInput input = activePage.getActiveEditor().getEditorInput();
String name = activePage.getActiveEditor().getEditorInput().getName();
//Path of files in the workspace.
IPath path = input instanceof FileEditorInput ? ((FileEditorInput) input).getPath() : null;
if (path != null) {
return path.toPortableString();
}
//Path of the externally opened files in Editor context.
try {
URI urlPath = input instanceof FileStoreEditorInput ? ((FileStoreEditorInput) input).getURI() : null;
if (urlPath != null) {
return new File(urlPath.toURL().getPath()).getAbsolutePath();
}
} catch (MalformedURLException e) {
e.printStackTrace();
}
//Fallback option to get at least name
return name;
}

How to get the file if I know the root directory and relative path?

In Dart, if I know the root directory and the relative path of a file, how to create a file instance for it?
Directory root = new Directory("/root");
String relativePath = "logs/users.log";
How to create a file instance for the users.log?
In java, it's very simple:
new File(root, relativePath);
But in Dart, I can't find a simple solution as that.
This is the simplest solution I found
import 'package:path/path.dart' as path;
...
String filePath = path.join(root.path, relativePath);
filePath = path.normalize(filePath);
File f = new File(filePath);
Joining /home/name/ and ../name2 to yield /home/name2
Edit:
Thank you Günter Zöchbauer for the tip.
It seems linux boxes can handle a path like /home/name/../name2.
On a windows machine, Path.normalize needs to be used and the extra / Path.normalize preppends at the head must be removed.
Or use new Path.Context():
import 'package:path/path.dart' as Path;
import 'dart:io' show Platform,Directory;
to_abs_path(path,[base_dir = null]){
Path.Context context;
if(Platform.isWindows){
context = new Path.Context(style:Path.Style.windows);
}else{
context = new Path.Context(style:Path.Style.posix);
}
base_dir ??= Path.dirname(Platform.script.toFilePath());
path = context.join( base_dir,path);
return context.normalize(path);
}
I found that problem to find relative path of a file inside of my test script file, so I improved the answer of #TastyCatFood to work in that context too. The following script can find the relative of a file every where:
import 'dart:io';
import 'package:path/path.dart' as path;
/// Find the path to the file given a name
/// [fileName] : file name
/// [baseDir] : optional, base directory to the file, if not informed, get current script path.
String retrieveFilePath(String fileName, [String baseDir]){
var context;
// get platform context
if(Platform.isWindows) {
context = path.Context(style:path.Style.windows);
} else {
context = path.Context(style:path.Style.posix);
}
// case baseDir not informed, get current script dir
baseDir ??= path.dirname(Platform.script.path);
// join dirPath with fileName
var filePath = context.join(baseDir, fileName);
// convert Uri to String to make the string treatment more easy
filePath = context.fromUri(context.normalize(filePath));
// remove possibles extra paths generated by testing routines
filePath = path.fromUri(filePath).split('file:').last;
return filePath;
}
The following example read the file data.txt in the same folder of main.dart file:
import 'package:scidart/io/io.dart';
main(List<String> arguments) async {
File f = new File('data.txt');
}

Resources