I have jar file containing two folders each with a bunch of files (and possibly some other files in the root):
myjar.jar
> sub1
> file1.txt
> file2.txt
> file3.txt
> ...
> sub2
> file1.txt
> file2.txt
> file3.txt
> ...
> otherfile.txt
I have another project that depends on myjar.jar that contains an application that needs to read all the resources/text file and for each resource convert them into a string. Therefore I would like to do
URL url = this.class.getClassLoader().getResource("sub1");
// Somehow iterate all sub urls and convert to string
Any good suggestion for doing this? One approach could be:
String scheme = url.getProtocol();
if (!"jar".equals(scheme)) {
// Hm who if we simply want to run from the workspace???
throw new IllegalArgumentException("Unsupported scheme: " + scheme);
}
JarURLConnection con = (JarURLConnection) url.openConnection();
JarFile archive = con.getJarFile();
Enumeration<JarEntry> entries = archive.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
if (entry.getName().startsWith(folder)) {
System.out.println(entry.getName());
}
}
but I would like to avoid this low-level code.
Related
I need to print the keys of Localizable.strings in my App, instead of their values (for a debugging purpose). Is there a fast way to override the NSLocalizedString() method or redefine the macro, something like:
#define NSLocalizedString(key, comment) NSLocalizedString(key, key)
One option would be to export your app for localizations via Product Menu > Export Localizations within Xcode, then save the xcloc file to your Desktop.
After which you could use a python script to parse the inner xliff (xml) to find the file elements with original attributes which contain Localizable.strings and print the trans-unit's source element text within the body of them. Here's an example of a python script which should do it localizationKeys.py:
import sys
import os.path
from xml.etree import ElementTree as et
import argparse as ap
import re
if __name__ == '__main__':
parser = ap.ArgumentParser()
# filename argument ex: de.xliff
parser.add_argument('filename', help="filename of the xliff to find keys ex:de.xliff")
# verbose flag
parser.add_argument('-v', '--verbose', action='store_true', default=False, help='Show all the output')
args = parser.parse_args()
if (os.path.isfile(args.filename)):
tree = et.parse(args.filename)
root = tree.getroot()
match = re.match(r'\{.*\}', root.tag)
ns = match.group(0) if match else ''
files = root.findall(ns + 'file')
for file in files:
originalAttr = file.attrib['original']
# find all files which contain Localizable.strings
if originalAttr != None and 'Localizable.strings' in originalAttr:
if args.verbose == True:
print("----- Localizations for file: " + originalAttr + " -----")
# grab the body element
bodyElement = file.find(ns + 'body')
# get all the trans-units
transUnits = bodyElement.findall(ns + 'trans-unit')
for transUnit in transUnits:
# print all the source values (keys)
print(transUnit.find(ns + 'source').text)
else:
print("No file found with the specified name: " + args.filename)
Which you could then use as follows:
python3 localizationKeys.py en.xcloc/Localized\ Contents/en.xliff
Or if you'd prefer to print to to a file instead
python3 localizationKeys.py en.xcloc/Localized\ Contents/en.xliff > output.txt
This could almost definitely be more concise using xpath instead, but this is just what I came up with quickly.
Ok, this is how I obtained what I needed
// Overriding NSLocalizedString to print keys instead of values
#ifdef NSLocalizedString
#undef NSLocalizedString
#endif
#define NSLocalizedString(key, comment) key
In this way the App use the keys instead of the values
I have an NativeScript 6.8 Javascript app that downloads newer data files. I'm discovering that on iOS I cannot create files within the app folder. (At least, in release builds; in debug builds I can.) I can change my code to read data files from the Documents folder, but how can I pre-populate the Documents folder at build time with the original data files? I'd rather not copy all the data files at run time.
Or, have I misinterpreted the restriction that files cannot be created in the app folder (or subfolders) in iOS release builds?
Live-updating files on iOS is more involved than one might expect. So, yes, you need to access the live-updated files from the Documents folder, not back the files up to iCloud, and handle numerous timing conditions, such as the live-update running just before what would seem to be the initial copy of the file to the Documents folder (seems unlikely, but I've seen it happen while testing).
I've included the function I developed, below. For context, when I find a file online to be live-updated, I use an appSetting to save the file's date as a string (storing as a value loses precision).
The function isn't perfect, but for now, it gets the job done. I call this from app.js in a NativeScript 6.8 JavaScript project.
/**
* Copy files in app/files folder to Documents folder so they can be updated
*/
async function copyFilesToDocuments() {
let filesCopied = appSettings.getBoolean("copyFilesToDocuments", false);
if (!filesCopied) { // only copy files on first invocation
let filesFolder = fs.knownFolders.currentApp().getFolder("files"); // Folder object
let documentsFolder = fs.knownFolders.documents(); // Folder object
let fileEntities = await filesFolder.getEntities();
for (entity of fileEntities) {
let sourceFile = fs.File.fromPath(entity.path);
let targetFilePath = fs.path.join(documentsFolder.path, entity.name);
let targetDate = parseInt(appSettings.getString(entity.name, "0"), 10); // live-update date or 0
if (fs.Folder.exists(targetFilePath) && targetDate > global.dataDate ) { // if file has been live-updated
console.log("app.js copyFilesToDocuments: file '" + entity.name + "' skipped to avoid overwrite. ");
continue; // don't overwrite newer file
}
appSettings.remove(entity.name); // remove any live-update timestamp
let targetFile = fs.File.fromPath(targetFilePath);
let content = await sourceFile.read();
try {
await targetFile.write(content);
if (platform.isIOS) {
// Prevent file from being backed up to iCloud
// See https://stackoverflow.com/questions/58363089/using-nsurlisexcludedfrombackupkey-in-nativescript
// See https://stackoverflow.com/questions/26080120/cfurlcopyresourcepropertyforkey-failed-because-passed-url-no-scheme
NSURL.fileURLWithPath(targetFilePath).setResourceValueForKeyError(true, NSURLIsExcludedFromBackupKey);
}
// console.log("app.js copyFilesToDocuments file copied: " + entity.name);
} catch(e) {
console.warn("app.js copyFilesToDocuments error: " + e);
//TODO: app will fail at this point with some files not found :-(
} // end catch
} // end for
appSettings.setBoolean("copyFilesToDocuments", true);
} // end files not yet copied
} // end copyFilesToDocuments
Does Perl6 have something like the Perl5 -T file test to tell if a file is a text file?
There's nothing built in, however there is a module Data::TextOrBinary that does that.
use Data::TextOrBinary;
say is-text('/bin/bash'.IO); # False
say is-text('/usr/share/dict/words'.IO); # True
That's a heuristic that has not been translated to Perl 6. You can simply read it in UTF8 (or ASCII) to do the same:
given slurp("read-utf8.p6", enc => 'utf8') -> $f {
say "UTF8";
}
(substitute read-utf8.p6 by the name of the file you want to check)
we can make use of the File::Type with the following code.
use strict;
use warnings;
use File::Type;
my $file = '/path/to/file.ext';
my $ft = File::Type->new();
my $file_type = $ft->mime_type($file);
if ( $file_type eq 'application/octet-stream' ) {
# possibly a text file
}
elsif ( $file_type eq 'application/zip' ) {
# file is a zip archive
}
Source: https://metacpan.org/pod/File::Type
I am creating a Yeoman generator app. I want to create a set of parent directories and each parent directory has the same set of child templates.
Right now I am using the below commands repeatedly to achieve this. Is there a better way to loop over an array and achieve the same?
this.mkdir('app/scss/modules/tables');
this.mkdir('app/scss/modules/navigation');
this.mkdir('app/scss/modules/pagination');
this.copy('_extends.scss', 'app/scss/modules/navigation/_extends.scss');
this.copy('_mixins.scss', 'app/scss/modules/navigation/_mixins.scss');
this.copy('_variables.scss', 'app/scss/modules/navigation/_variables.scss');
this.copy('_extends.scss', 'app/scss/modules/pagination/_extends.scss');
this.copy('_mixins.scss', 'app/scss/modules/pagination/_mixins.scss');
this.copy('_variables.scss', 'app/scss/modules/pagination/_variables.scss');
this.copy('_extends.scss', 'app/scss/modules/tables/_extends.scss');
this.copy('_mixins.scss', 'app/scss/modules/tables/_mixins.scss');
this.copy('_variables.scss', 'app/scss/modules/tables/_variables.scss');
I reckon you'd need two arrays, and at least two loops.
In pseudocode:
dirs = [ ... directories ... ];
files = [ ... files ... ];
for (directory in dirs) {
mkdir (d);
for (file in files) {
copy(file, directory + file);
}
}
If you ever need another directory with all files, or another file to go in all directories you'd just add it to the corresponding array.
Hope you find this useful!
You could also do something like this:
dirs = [ "folder1", "folder2", "etc" ];
files = [ "file1", "file2", "etc" ];
dirs.forEach(function(directory){
this.mkdir(directory);
files.forEach(function(file){
this.copy(file, directory + file);
}.bind(this));
}.bind(this));
...if you want to avoid using a 'for-in' loop, since they're somewhat error-prone.
What is the easiest method for joining/merging all files in a folder (tab delimited) into a single file? They all share a unique column (primary key). Actually, I only need to combine a certain column and link on this primary key, so the output file would contain a new column for each file. Ex:
KEY# Ratio1 Ratio2 Ratio3
1 5.1 4.4 3.3
2 1.2 2.3 3.2
etc....
There are many other columns in each file that I don't need to combine in the output file, I just need these "ratio" columns linked by the unique key column.
I am running OS X Snow Leopard but have access to a few Linux machines.
use the join(1) utility
I actually spent some time learning Perl and solved the issue on my own. I figured I'd share the source code if anyone has a similar problem to solve.
#!/usr/bin/perl -w
#File: combine_all.pl
#Description: This program will combine the rates from all "gff" files in the current directory.
use Cwd; #provides current working directory related functions
my(#handles);
print "Process starting... Please wait this may take a few minutes...\n";
unlink"_combined.out"; #this will remove the file if it exists
for(<./*.gff>){
#file = split("_",$_);
push(#files, substr($file[0], 2));
open($handles[#handles],$_);
}
open(OUTFILE,">_combined.out");
foreach (#files){
print OUTFILE"$_" . "\t";
}
#print OUTFILE"\n";
my$continue=1;
while($continue){
$continue=0;
for my$op(#handles){
if($_=readline($op)){
my#col=split;
if($col[8]) {
$gibberish=0;
$col[3]+=0;
$key = $col[3];
$col[5]+=0; #otherwise you print nothing
$col[5] = sprintf("%.2f", $col[5]);
print OUTFILE"$col[5]\t";
$continue=1;
} else {
$key = "\t";
$continue=1;
$gibberish=1;
}
}else{
#do nothing
}
}
if($continue != 0 && $gibberish != 1) {
print OUTFILE"$key\n";
} else {
print OUTFILE"\n";
}
}
undef#handles; #closes all files
close(OUTFILE);
print "Process Complete! The output file is located in the current directory with the filename: _combined.out\n";