FileStatus use to recurse directory - recursion

I have following directory structure,
Dir1
|___Dir2
|___Dir3
|___Dir4
|___File1.gz
|___File2.gz
|___File3.gz
The subdirectories are just nested and donot contain any files
I am trying to use the following for recursing through a directory on HDFS.If its a directory I append /* to the path and addInputPath
arg[0] = "path/to/Dir1"; // given at command line
FileStatus fs = new FileStatus();
Path q = new Path(args[0]);
FileInputFormat.addInputPath(job,q);
Path p = new Path(q.toString()+"/*");
fs.setPath(p);
while(fs.isDirectory())
{
fs.setPath(new Path(p.toString()+"/*"));
FileInputFormat.addInputPath(job,fs.getPath());
}
But the code doesnt seem to go in the while loop and I get not a File Exception

Where is the if statement you are referring to?
Anyway, you may have a look at these utility methods which add all files within a directory to a job's input:
Utils:
public static Path[] getRecursivePaths(FileSystem fs, String basePath)
throws IOException, URISyntaxException {
List<Path> result = new ArrayList<Path>();
basePath = fs.getUri() + basePath;
FileStatus[] listStatus = fs.globStatus(new Path(basePath+"/*"));
for (FileStatus fstat : listStatus) {
readSubDirectory(fstat, basePath, fs, result);
}
return (Path[]) result.toArray(new Path[result.size()]);
}
private static void readSubDirectory(FileStatus fileStatus, String basePath,
FileSystem fs, List<Path> paths) throws IOException, URISyntaxException {
if (!fileStatus.isDir()) {
paths.add(fileStatus.getPath());
}
else {
String subPath = fileStatus.getPath().toString();
FileStatus[] listStatus = fs.globStatus(new Path(subPath + "/*"));
if (listStatus.length == 0) {
paths.add(fileStatus.getPath());
}
for (FileStatus fst : listStatus) {
readSubDirectory(fst, subPath, fs, paths);
}
}
}
Use it in your job runner class:
...
Path[] inputPaths = Utils.getRecursivePaths(fs, inputPath);
FileInputFormat.setInputPaths(job, inputPaths);
...

Related

Drag an Outlook email into a JavaFX Application

I made a Javafx scene to handle drag-n-drop and it is working fine if you drag a file from the windows explorer or from the desktop for example.
However, if I try to do it from Outlook, the behavior is weird.
I realized that when you drag n drop from another program inside the dragboard component, the method "getContentTypes" will return a few DataFormat objects using this code:
dragField.setOnDragOver((DragEvent event) -> {
Dragboard db = event.getDragboard();
System.out.println(db.getContentTypes());
});
The output will be something like:
[text/plain] - De Objet Reçu Taille Catégories D D Test 13:56 40 Ko [DragImageBits] -
java.nio.HeapByteBuffer[pos=0 lim=90304 cap=90304]
[message/external-body;access-type=clipboard;index=0;name="testEmail.msg"] -
null [Object Descriptor] - java.nio.HeapByteBuffer[pos=0 lim=74
cap=74] [RenPrivateItem] - null [CSV] - java.nio.HeapByteBuffer[pos=0
lim=282 cap=282]
It seems to be able to extract the information from the Outlook msg file, since I got something like a header and also the "testEmail.msg" file name is correct.
However, when I try to use this code:
DataFormat.lookupMimeType("message/external-body;access-type=clipboard;index=0;name=\"testEmail.msg\"");
It returns null... In fact, there is a "null" by the mime-type side.
Is there any way to transform these DataFormat objects into a java file or maybe a apache poi msg file? Anything would be amazing.
Thanks for any help! :D
If there is a mime type starting with message/external-body;access-type=clipboard, you can get the value using
clipboard.getContent(new DataFormat("message/external-body"));
Here is an example which just saves the file:
private boolean clipboardHasInMemoryFile(Clipboard clipboard) {
for (DataFormat d: clipboard.getContentTypes()) {
if (d.toString().startsWith("[message/external-body;access-type=clipboard")) {
return true;
}
}
return false;
}
public void saveOutlookFile() throws IOException {
Clipboard clipboard = Clipboard.getSystemClipboard();
if (clipboardHasInMemoryFile(clipboard)) {
//this is for copying an outlook attachment
String name = "outfile";
for (DataFormat d : clipboard.getContentTypes()) {
if (d.toString().startsWith("[message/external-body;access-type=clipboard")) {
Pattern p = Pattern.compile("name=\"([^\"]*)\"");
Matcher m = p.matcher(d.toString());
m.find();
name = m.group(1);
break;
}
}
Object inMemoryFile = null;
try {
DataFormat df = DataFormat.lookupMimeType("message/external-body");
if (df == null) {
df = new DataFormat("message/external-body");
}
inMemoryFile = clipboard.getContent(df);
} catch (Throwable t) {
}
final String fileName = name;
if (inMemoryFile != null) {
if (inMemoryFile instanceof ByteBuffer) {
ByteBuffer b = (ByteBuffer) inMemoryFile;
byte bytes[] = b.array();
FileOutputStream fo = new FileOutputStream(fileName);
fo.write(b.array());
fo.close();
}
}
}
}

JGit's Status doesn't list any files when it should

I wrote a Spock test to learn how to use JGit. The general idea of the test follows these steps:
Create a "TestRepo" directory
Initialize a new Git repository there ("TestRepo/.git")
Create a new File in the parent directory (TestRepo) and set its text to something to take up space
Call "git status"
(debug) Groovy dump the returned Status object
Assert that the returned Status object has the file listed as untracked.
When I run the below test, it fails. Why?
state.dump() prints
Status#38989dff
diff=org.eclipse.jgit.lib.IndexDiff#72def3cd
clean=true
hasUncommittedChanges=false
Code below:
class GitActionsSpec extends Specification {
public static final ROOT_DIR_PATH = Paths.get(System.getProperty("user.home"), "TestRepo")
public static final ROOT_DIR_STRING = ROOT_DIR_PATH.toString()
public static final GIT_DIR_PATH = ROOT_DIR_PATH.resolve(".git")
#Shared
Git git
/**
* Creates a repository in rootDirPath
*/
def setupSpec() {
if (Files.exists(ROOT_DIR_PATH)) {
deleteDirectory(ROOT_DIR_PATH)
}
Files.createDirectory(ROOT_DIR_PATH)
/*
GitActions.createRepoIn(File parentDirectory) {
return Git.init().setDirectory(f).call()
}
*/
git = GitActions.createRepoIn(ROOT_DIR_PATH.toFile())
assert git.repository.getDirectory().exists()
}
// The actual test
def "A newly-created file should be listed as 'untracked'"() {
given: "A new file"
Path file = ROOT_DIR_PATH.relativize(ROOT_DIR_PATH.resolve("file.txt"))
file.text = "filler text"
assert Files.exists(file)
when: "user requests the status"
Status state = git.status().addPath(file.toString()).call()
then: "Git lists that file as untracked"
println state.dump()
!state.getUntracked().isEmpty()
}
def cleanupSpec() {
git.close()
deleteDirectory(ROOT_DIR_PATH)
}
def deleteDirectory(Path directory) {
Files.walkFileTree(directory, new SimpleFileVisitor<Path>() {
#Override
FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
Files.delete(dir)
return FileVisitResult.CONTINUE
}
#Override
FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file)
return FileVisitResult.CONTINUE
}
})
}
}
Turns out the issue lied in the code that sets up file.
File's toString() returns A, not B:
A: /home/user/Project/Module/file.txt
B: /home/user/TestRepo/file.txt

How to extract directory (and sub directories) from jar resource?

I've a dir (with sub dirs) template that is kept as a resource inside a jar file. During run
time I need to extract it (template) to tmp dir change some content and finally publish it as a zipped artifact.
My question is: how to extract this content easily? I was trying getResource() as well as getResourceAsStream()..
Following code works fine here: (Java7)
String s = this.getClass().getResource("").getPath();
if (s.contains("jar!")) {
// we have a jar file
// format: file:/location...jar!...path-in-the-jar
// we only want to have location :)
int excl = s.lastIndexOf("!");
s = s.substring(0, excl);
s = s.substring("file:/".length());
Path workingDirPath = workingDir = Files.createTempDirectory("demo")
try (JarFile jf = new JarFile(s);){
Enumeration<JarEntry> entries = jf.entries();
while (entries.hasMoreElements()) {
JarEntry je = entries.nextElement();
String name = je.getName();
if (je.isDirectory()) {
// directory found
Path dir = workingDirPath.resolve(name);
Files.createDirectory(dir);
} else {
Path file = workingDirPath.resolve(name);
try (InputStream is = jf.getInputStream(je);) {
Files.copy(is, file, StandardCopyOption.REPLACE_EXISTING);
}
}
}
}
} else {
// debug mode: no jar
}

How to store tree structure using neo4j and gremlin

I want to store following directory tree structure using neo4j local database and Gremlin in Java.
(ROOT)
/ \
Dir2 Dir3
/ \ \
Dir4 Dir5 Dir6
/
Dir7
I have defined a method StorePath(String path).
What i want : When i call StorePath(path) with path = "Root\Dir2\Dir4\Dir7" then data should be stored as follows
Root
/
Dir2
/
Dir4
/
Dir7
where Root and Dir* are vertices with blank edges.
Please help me with the java code.
private static final RelationshipType SUB_DIR = DynamicRelationshipType.withName("SUB_DIR");
public void storePath(String path) {
Node dir = graphDb.getReferenceNode();
for (String name : path.split(File.separator)) {
dir = obtainSubDir(dir, name);
}
}
private Node obtainSubDir(Node dir, String name) {
Node subDir = getSubDir(dir,name);
if (subDir!=null) return subDir;
return createSubDir(dir, name);
}
private Node getSubDir(Node dir, String name) {
for (Relationship rel : dir.getRelationships(SUB_DIR, Direction.OUTGOING)) {
final Node subDir = rel.getEndNode();
if (subDir.getProperty("name", "").equals(name)) return subDir;
}
return null;
}
private Node createSubDir(Node dir, String name) {
Node subDir = dir.getGraphDatabase().createNode();
subDir.setProperty("name", name);
dir.createRelationshipTo(subDir, SUB_DIR);
return subDir;
}

MethodAccessException when updating a record in sqlite db

I encounter this exception when I try to updating a record with following statement.
UPDATE GroupTable SET groupId=100 WHERE groupId=101
I tested the statement under SQLite Manager of Firefox plug-in, and it works.
The error message is as following image. It crashed at the os_win_c.cs, the method named getTempname().
Well, I modified the original codes and fixed this bug.
The Path.GetTempPath() doesn't work because the sandbox enviroment. It has no access right.
I fixed by following codes. And it works now.
static int getTempname(int nBuf, StringBuilder zBuf)
{
const string zChars = "abcdefghijklmnopqrstuvwxyz0123456789";
StringBuilder zRandom = new StringBuilder(20);
i64 iRandom = 0;
for (int i = 0; i < 20; i++)
{
sqlite3_randomness(1, ref iRandom);
zRandom.Append((char)zChars[(int)(iRandom % (zChars.Length - 1))]);
}
//! Modified by Toro, 2011,05,10
string tmpDir = "tmpDir";
IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication();
store.CreateDirectory(tmpDir);
//zBuf.Append(Path.GetTempPath() + SQLITE_TEMP_FILE_PREFIX + zRandom.ToString());
zBuf.Append(tmpDir + "/" + SQLITE_TEMP_FILE_PREFIX + zRandom.ToString());
return SQLITE_OK;
}
The above patch will result in an extra folder tmpDir in the isolatedstorage, and the temp files won't be deleted automatically, so it needs to be delete by self. I tried to delete those files in tmpDir in the method of winClose inside os_win_c.cs, and I found it will result in crash when I do VACUUM. Finally, I delete those tmp files when I closed the database. The following is a Dispose method in SQLiteConnection class.
public void Dispose()
{
if (_open)
{
// Original codes for close sqlite database
Sqlite3.sqlite3_close(_db);
_db = null;
_open = false;
// Clear tmp files in tmpDir, added by Toro 2011,05,13
IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication();
string tmpDir = "tmpDir";
if (store.DirectoryExists(tmpDir) == false) return;
string searchPath = System.IO.Path.Combine(tmpDir, "*.*");
foreach (string file in store.GetFileNames(searchPath)) {
store.DeleteFile(System.IO.Path.Combine(tmpDir, file));
}
}
}

Resources