Dart: Replace content inside file using RandomAccessFile - dart

I am trying to replace content inside a file using RandomAccessFile class of "dart".
My file content is : Hello user World
My dart code is:
import 'dart:io';
main() async{
File file = File("test/testraf.txt");
RandomAccessFile raf = await file.open(mode: FileMode.writeOnly);
var f1 = await raf.setPosition(7);
f1.writeString("John");
f1.close();
}
I am trying to replace user with John.
But above code corrupts my file and do not do the intended work.
This is what I intended to do : Hello John World
How do I replace content inside a file using random writes ?
Is it possible, my requirement is to replace data at random position inside a file, without creating another copy of the file ?

ok So guys the problem was file mode must be : FileMode.writeOnlyAppend.
The working code will be :
import 'dart:io';
main() async{
//File content: Hello user World
File file = File("test/testraf.txt");
RandomAccessFile raf = await file.open(mode: FileMode.writeOnlyAppend);
var f1 = await raf.setPosition(6);
await f1.writeString("John");
await f1.close();
}
So it will output : Hello John World

Related

How to fix undefined File() class and its methods in Dart?

I want to save files in local storage of Android/iOS. I followed the Flutter cookbook to save files but it didn't work. There are examples everywhere using the File class, but it's undefined when I use it. I'm using Dart 2.2.0 and Flutter 1.2.1
I've tried example code snippets from a few websites. Nothing worked. File class, readAsString, and writeAsString are undefined in my Dart file.
Here's the code. Checked it in DartPad. Where am I wrong?
//packages
import 'dart:io';
import 'dart:async';
import 'package:path_provider/path_provider.dart';
//start
class File {
/// Directory Path
/// Local Directory Path
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();
// For your reference print the AppDoc directory
print(directory.path);
return directory.path;
}
/// Reference for file Location
Future<File> get _localFile async {
final path = await _localPath;
final address = '$path/data.txt';
return File(address);
}
/// Presenting different Data as 1 String
String convertingtoString(String title, String author, String content) {
return '$title\n$author\n\n$content';
}
/// Write to file
/// Writing as String
Future<File> writeContent(String matter) async {
/// Get matter converted to string as matter
final file = await _localFile;
// Write the file
return file.writeAsString(matter);
}
/// Read from file
Future<String> readcontent() async {
try {
final file = await _localFile;
// Read the file
String contents = await file.readAsString();
return contents;
} catch (e) {
// If there is an error reading, return a default String
return 'Error, Couldn\'t read file';
}
}
}
This is code from my android flutter project. I get the same errors like DartPad in VScode
You've created your own class named File, so that hides the File class from dart:io. Name your custom class something else, or do:
import 'dart:io' as io;
and use io.File where you intend to use dart:io's File class. (I recommend renaming your custom class to avoid confusion.)
Original answer
Since you have import 'dart:io';, the File class should be available to you.
If you're trying this solely with DartPad, then it (among other things) won't work there because dart:io is meant to be used with a Dart VM. dart:io won't work in a browser, which has a sandboxed environment and generally prevents filesystem access:
Important: Browser-based applications can't use this library. Only servers, command-line scripts, and Flutter mobile apps can import and use dart:io.

How do I create a "fake" dart:io File from in-memory bytes?

I have the in-memory bytes of a "blob", but the API that I want to process this "blob" with only accepts dart:io File objects.
Is there a way to create a "fake" dart:io File , simply wrapping my in-memory bytes, so that I can pass this "fake" File to my API?
Assume that a file system doesn't exist, and assume that I can't write the in-memory bytes to a "real" file.
Thanks!
You can create a memory-file using MemoryFileSystem from the package file:
Example:
File file = MemoryFileSystem().file('test.dart')
..writeAsBytesSync(blobBytes);
Add path provider dependency on pubspec.yaml
dependencies:
path_provider: 0.2.2
Write byte data to file, use it, then delete it.
import 'dart:io';
import 'package:path_provider/path_provider.dart';
main() async {
String dir = (await getTemporaryDirectory()).path;
File temp = new File('$dir/temp.file');
var bytes = [0, 1, 2, 3, 4, 5];
await temp.writeAsBytes(bytes);
/*do something with temp file*/
temp.delete();
}
You can override the io using the IOOverides class. See the below example:
await IOOverrides.runZoned(() async {
// Write your code here.
},
createDirectory: (p0) {
return MockDirectory()
},
createFile: (p0) {
return MockeFile();
},
);
You can check the doc here for more info.
I always use cross_file when designing APIs that work with files.
In addition to working on multiple platforms, it also has an XFile.fromData constructor that allows you to create a file in memory.

Code cannot find a line on a website

I've been trying to find a line and print it out on this website: http://www.easports.com/player-hub/360/Its+McDoom
Right now it prints out everything on the website, but I cannot find the line I am looking for. I am trying to print out "H2h Skill Points: 1053", but I cannot find anything like that in the console.
I only really want it to print that 1 line, not the whole thing, but I can't even find it.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
public class ElectronicArtsStatHub {
/**
* #param args
*/
public static void main (String[] args) throws Exception{
URL oracle = new URL("http://www.easports.com/player-hub/360/Its+McDoom");
URLConnection yc = oracle.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(
yc.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println(inputLine);
}
in.close();
}
}
The first problem is that the information your trying to find isn't actually in the data you are currently outputting.
When you open the page in your browser you get the main page elements but then your browser then runs some Javascript code which presumably uses AJAX to get the stats and fill in the table.
The URLConnection receives the same data that your browser initially does and does not execute the Javascript so if you check your output that data your looking for isn't actually there at all.
Possible solutions include finding a different source for this data or executing the Javascript in Java possibly by using HTMLUnit
There may be some helpful infomation on this related question

Dart directory scan and list population

I'm new to this dart stuff and having problems with creating a list with file names from a directory. The example code makes sense but doesn't work and provides no error messages.
I'm really not enjoying how Dart complicates simple tasks.
var flist = new List();
Process.run('cmd', ['/c', 'dir *.txt /b']).then((ProcessResult results) {
flist.add(results.toString());
});
i know it's way off.. how do i go about this without having to call any outside voids.. i'd like to keep my code in the 'main' function.
You might find this answer useful. It shows how to use the Directory object to list contents of a directory: How do I list the contents of a directory with Dart?
Looks like you're trying to find all files in a directory that end in *.txt. You could do this:
import 'dart:io';
main() {
var dir = new Directory('some directory');
var contents = dir.listSync();
var textFiles = contents.filter((f) => f.name.endsWith('.txt'));
}

How do I list the contents of a directory with Dart?

I would like to list all the contents of a directory (on the file system) using Dart. How can I do this?
How to list the contents of a directory in Dart
final dir = Directory('path/to/directory');
final List<FileSystemEntity> entities = await dir.list().toList();
This creates a Directory from a path. Then it converts it to a list of FileSystemEntity, which can be a File, a Directory, or a Link. By default subdirectories are not listed recursively.
If you want to print that list, then add this line:
entities.forEach(print);
If you want to only get the files then you could do it like so:
final Iterable<File> files = entities.whereType<File>();
The API has changed and I have updated the async code for M4 release (0.5.16_r23799 ):
Future<List<FileSystemEntity>> dirContents(Directory dir) {
var files = <FileSystemEntity>[];
var completer = Completer<List<FileSystemEntity>>();
var lister = dir.list(recursive: false);
lister.listen (
(file) => files.add(file),
// should also register onError
onDone: () => completer.complete(files)
);
return completer.future;
}
The list method returns a Stream where each emitted event is a directory entry:
Directory dir = Directory('.');
// execute an action on each entry
dir.list(recursive: false).forEach((f) {
print(f);
});
As the name suggest, listSync method is the blocking version:
// create a list of entries
List<FileSystemEntity> entries = dir.listSync(recursive: false).toList();
What method to use depends on application context. A note directly from the docs:
Unless you have a specific reason for using the synchronous version of a method, prefer the asynchronous version to avoid blocking your program.
This answer is out of date. Please see the accepted answer.
There are two ways to list the contents of a directory using the Dart VM and the dart:io library.
(note: the following only works in the Dart VM when running on the command-line or as a server-side app. This does not work in a browser or when compiled to JavaScript.)
Setup
First, you need to import the dart:io library. This library contains the classes required to access files, directories, and more.
import 'dart:io';
Second, create a new instance of the Directory class.
var dir = new Directory('path/to/my/dir');
Listing contents in a script
The easiest way is to use the new listSync method. This returns a List of contents. By default this does not recurse.
List contents = dir.listSync();
for (var fileOrDir in contents) {
if (fileOrDir is File) {
print(fileOrDir.name);
} else if (fileOrDir is Directory) {
print(fileOrDir.path);
}
}
If you want to recurse through directories, you can use the optional parameter recursive.
List allContents = dir.listSync(recursive: true);
WARNING if your directory structure has circular symlinks, the above code will crash because it's following symlinks recursively.
This method, using listSync, is especially useful when you are writing a shell script, command-line utility, or similar app or script with Dart.
Listing contents in a server
A second way to list the contents of a directory is to use the async version of list. You would use this second method when you need to list a directory in response to, say, an HTTP request. Remember that each of Dart's isolates runs in a single thread. Any long running process can block the event loop. When interactivity is important, or serving lots of clients from a single Dart script, use the async version.
With the async version, dir.list() returns a DirectoryLister. You can register three different callbacks on DirectoryLister:
onFile: called when a file or directory is encountered
onDone: called when the directory lister is done listing contents
onError: called when the lister encounters some error
Here is a simple function that returns a Future of a list of strings, containing file names in a directory:
Future<List<String>> dirContents(Directory dir) {
var filenames = <String>[];
var completer = new Completer();
var lister = dir.list();
lister.onFile = (filename) => filenames.add(filename);
// should also register onError
lister.onDone = (_) => completer.complete(filenames);
return completer.future;
}
Of course, this method is perfect for servers, it's more cumbersome for simple scripts.
Luckily, Dart supports both methods for you to use!
Inside and asynchronous function write this
List<FileSystemEntity> allContents = await Directory("folder/path").list().toList();
Now you have a list with all of the contents
Here is my version using async/await, returning a List of Files only:
List<File> filesInDirectory(Directory dir) async {
List<File> files = <File>[];
await for (FileSystemEntity entity in dir.list(recursive: false, followLinks: false)) {
FileSystemEntityType type = await FileSystemEntity.type(entity.path);
if (type == FileSystemEntityType.FILE) {
files.add(entity);
print(entity.path);
}
}
return files;
}
With this function you can print all the directories and files of a directory.
You just need to pass a specific path.
Future listDir(String folderPath) async {
var directory = new Directory(folderPath);
print(directory);
var exists = await directory.exists();
if (exists) {
print("exits");
directory
.list(recursive: true, followLinks: false)
.listen((FileSystemEntity entity) {
print(entity.path);
});
}
}
To get a list of file names with a certain string, you can use this code:
String directory = (await getApplicationDocumentsDirectory()).path;
List<FileSystemEntity> files = Directory(directory).listSync(recursive: false);
List<String> filePaths = [];
for (var fileSystemEntity in files) {
if (basename(fileSystemEntity.path).contains('mystring')) {
filePaths.add(fileSystemEntity.path);
}
}
You can use the basename function if you need just the file name, and not the whole path.
To get all files with given extension:
import 'package:path/path.dart' as p;
Future<List<File>> getAllFilesWithExtension(String path, String extension) async {
final List<FileSystemEntity> entities = await Directory(path).list().toList();
return entities.whereType<File>().where((element) => p.extension(element.path) == extension).toList();
}

Resources