how to list files and directories in current directory without using java.io.*?
This is actually possible without having to write any JNI or make any Runtime calls.
import java.net.URL;
import sun.net.www.content.text.PlainTextInputStream;
public class NoIO {
public static void main(String args[]) {
NoIO n = new NoIO();
n.doT();
}
public void doT() {
try {
//Create a URL from the user.dir (run directory)
//Prefix with the protocol file:/
//Users java.net
URL u = new URL("file:/"+System.getProperty("user.dir"));
//Get the contents of the URL (this basically prints out the directory
//list. Uses sun.net.www.content.text
PlainTextInputStream in = (PlainTextInputStream)u.getContent();
//Iterate over the InputStream and print it out.
int c;
while ((c = in.read()) != -1) {
System.out.print((char) c);
}
} catch(Exception e) {
e.printStackTrace();
}
}
}
It's amazing what a little thought and boredom will do (and an inability to jump to hasty conclusions (where there's a will, there's a way)).
You could probably also do it using the ClassLoader, by overriding it, at some point Java has to iterate over all the files in the classpath, by hooking at that point you can print out all the files that it tries to load without using any kind of java.io.*.
After some investigation I don't think this is possible very easily, certainly not for a homework assignment unless it's some kind of RE'ing assignment or Forensics assignment.
You can use Runtime.getRuntime().exec():
String[] cmdarray;
if (System.getProperty("os.name").startsWith("Windows")) {
cmdarray = new String[] { "cmd.exe", "/c", "dir /b" };
} else { // for UNIX-like systems
cmdarray = new String[] { "ls" };
}
Runtime.getRuntime().exec(cmdarray);
Thanks to #Geo for the Windows commands.
You could use JNA to make native calls to the underlying OS.
As an exercise in hard work it might be a worth while.
Another option is writing OS specific code in C and accessing it via JNI. But once again. Why do you want this?
Related
I want my program to be able to detect whether OBS-Studio is currently running, and if it is, perform certain functionality in my program. The problem is I can't seem to find a solution that will work on both platforms. I've found things that use taskList, wmic.exe and others on windows, and I've found things using top, ps aux and others on linux, however these are very platform specific, and not easily ported. Is there a universal use case, and if so, what might it be?
I'm aware of ProcessHandle in Java9+, however my program runs Java8, with no current hope of upgrading, so that's not possible.
I Cannot think of a solution that will work on both platforms,
maybe use something like below to determine the operating system in Java then from there, use a conditional statement to execute the portion of the code appropriate for your host machine.
os = System.getProperty("os.name");
I hope this helps
I ended up creating a method that would return a Map<Integer, String> for all processes by running os-specific commands:
public Map<Integer, String> getProcesses() {
final Map<Integer, String> processes = Maps.newHashMap();
final boolean windows = System.getProperty("os.name").contains("Windows");
try {
final Process process = Runtime.getRuntime().exec(windows ? "tasklist /fo csv /nh" : "ps -e");
try (final BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
reader.lines().skip(1).forEach(x -> { // the first line is usually just a line to explain the format
if (windows) {
// "name","id","type","priority","memory?"
final String[] split = x.replace("\"", "").split(",");
processes.put(Integer.valueOf(split[1]), split[0]);
}
else {
// id tty time command
final String[] split = Arrays.stream(x.trim().split(" ")).map(String::trim)
.filter(s -> !s.isEmpty()).toArray(String[]::new); // yikes
processes.put(Integer.valueOf(split[0]), split[split.length - 1]);
}
});
}
}
catch (IOException e) {
e.printStackTrace();
}
return processes;
}
This hasn't been tested on Windows, but it should work. It also hasn't been tested on literally anything else other than Linux, but I hope this serves as a helpful method for others to work off of.
To begin, I'm aware of this question, but I don't think it quite fits what I'm doing. Either way, the answer is a bit confusing my opinion. I'd like to find an answer for my problem that's more specific to what I'm doing.
The goal here is for the lua file chatterToolsTest to successfully print "Test success" to the console. Unfortunately, my current approach isn't quite working. Can someone please help? I'm not the best at Lua, so maybe my Lua code is just wrong in this case. Please check out the snippets below.
Another constraint: I can't enable to use of modules from the java-side. Any referencing done between the two Lua files has to be obtained through Lua only. This is because I'm developing a modding system for a Java project and need the Lua to be able to work with minimal change on the Java-side.
Please keep in mind that I'm not storing my Lua files inside of the JAR file or any packages, they are contained in a folder in the root working directory of the Java program, like a folder of resources.
chatterToolsTest.lua:
function main()
print("Test start.");
local test = require("chatterTools");
chatterTools:test();
end
chatterTools.lua, the class called by chatterToolsTest.lua:
function test()
print("Test success");
end
Both of these files are in a folder called world/NOKORIWARE/lua/:
And lastly, here's the Java test class using LuaJ that calls them:
public class LuaTest {
public static void main(String args[]) {
new LuaTest().run("NOKORIWARE/lua/chatterToolsTest.lua", "main");
}
private Globals buildGlobals() {
Globals globals = new Globals();
globals.load(new JseBaseLib());
globals.load(new PackageLib());
globals.load(new Bit32Lib());
globals.load(new TableLib());
globals.load(new StringLib());
globals.load(new JseMathLib());
globals.load(new WhitelistedLuajavaLib());
LoadState.install(globals);
LuaC.install(globals);
return globals;
}
/**
* Runs the given lua file. It must be relative to the lua path.
*/
private void run(String luaPath, String functionName, Object... arguments) {
LuaValue[] coercedValues = null;
if (arguments != null) {
//Coerce arguments into LuaValues
coercedValues = new LuaValue[arguments.length];
for (int i = 0; i < arguments.length; i++) {
coercedValues[i] = CoerceJavaToLua.coerce(arguments[i]);
}
}
//Configure lua file
Globals globals = buildGlobals();
globals.get("dofile").call(LuaValue.valueOf("./world/" + luaPath));
//Call the passed-in function of the lua file.
try {
LuaValue call = globals.get(functionName);
if (arguments != null) {
call.invoke(coercedValues);
}else {
call.invoke();
}
} catch (Exception e) {
e.printStackTrace();
TinyFileDialog.showMessageDialog("Caught " + e.getClass().getName(), e.getMessage(), TinyFileDialog.Icon.INFORMATION);
}
}
}
This is the error that's printed when I run the Java program:
org.luaj.vm2.LuaError: #./world/NOKORIWARE/lua/chatterToolsTest.lua:4 module 'chatterTools' not found: chatterTools
no field package.preload['chatterTools']
chatterTools.lua
no class 'chatterTools'
at org.luaj.vm2.LuaValue.error(Unknown Source)
at org.luaj.vm2.lib.PackageLib$require.call(Unknown Source)
at org.luaj.vm2.LuaClosure.execute(Unknown Source)
at org.luaj.vm2.LuaClosure.onInvoke(Unknown Source)
at org.luaj.vm2.LuaClosure.invoke(Unknown Source)
at org.luaj.vm2.LuaValue.invoke(Unknown Source)
at nokori.robotfarm.test.LuaTest.run(LuaTest.java:64)
at nokori.robotfarm.test.LuaTest.main(LuaTest.java:21)
Any help or links to relevant resources is appreciated.
The default LuaJ working directory is the same as Java's. Once I figured that out, I was able to correctly use require().
chatterTools.lua was changed to this:
local chatterTools = {}
function chatterTools.test()
print("Test success");
end
return chatterTools;
And finally chatterToolsTest.lua had to be changed like this:
function main()
print(package.path);
local chatterTools = require("world.NOKORIWARE.lua.chatterTools");
chatterTools:test();
end
Lua handles packages like above, so instead of world/NOKORIWARE/lua/chatterTools.lua it turns into what you see in the require() call.
After these changes, I ran the program and got the following:
?.lua
Test success
All of this considered, this solution is a lot more straight-forward than the answer in the question I linked at the start of this question. Hopefully this will help some of you out there.
To read more on how I figured this out, check these resources out:
how to call function between 2 .lua
https://forums.coronalabs.com/topic/38127-how-to-call-a-function-from-another-lua-file/
I have a project in RAD. Package is inputFileEdit, and the java class I need is InputFileTest.java.
package inputFileEdit;
public class InputFileTest {
public static void main(String[] args) {
String var1 = args[0];
String var2 = args[1].toLowerCase();
// do stuff with args
}
}
I want to create a new package / java program that can call or instantiate the class InputFileTest above, with arguments, multiple times in parallel. I'm basically going to be bringing back a String list, looping through that list to create parallel threads, each row on the list calling InputFileTest.
Question 1) What's the best way to call InputFileTest? I'm using RAD and I created a new Project, a package called CallerPackage, and a Caller.java inside that package? I also including a "Jar" of the whole InputFileEdit project under /lib via Java Build Path -> Libraries -> Add External Jars. I don't know how to call the class with parameters (I tried something like InputFileEdit ifeObj = new InputFileEdit("parm 1", "parm 2"); or InputFileEdit ifeObj = new InputFileEdit("parm 1 parm 2");) but neither worked so then I tried to just call the jar like Process p = Runtime.getRuntime().exec("java -jar /lib/InputFileEdit.jar parm1 parm2"); or since I want the actual Class InputFileTest, Process p = Runtime.getRuntime().exec(new String[]{"java","-cp","/lib/InputFileEdit.jar", "InputFileTest", "parm1","parm1"});:
package CallerPackage;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
//import inputFileEdit.*;
public class Caller {
static int i = 0;
public static void main(String args[]) throws IOException, InterruptedException {
try {
System.out.println("Calling jar");
Process p = Runtime.getRuntime().exec("java -jar /lib/InputFileEdit.jar parm1 parm2");
BufferedInputStream errStrm = new BufferedInputStream(p.getErrorStream());
// get the error stream of the process and print it
for (int i = 0; i < errStrm.available(); i++) {
System.out.println("" + errStrm.read());
}
System.out.println("Called jar");
p.destroy();
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}
but this doesn't seem to work either or print out anything helpful. Any ideas of the best way to go about this? I'm only trying to get 1 call to work for now before I loop through my list and call them in parallel. Eventually it'll be calling the jar/class looping through a string arraylist.
you should be able to call the main method in InputFileTest the same way you would call any other static method: InputFileTest.main(args);
However, generally directly calling main is frowned upon. If you are able, I would advise you to take the code in InputFileTest's main, and put it into another, more descriptively named method, something like processFiles.
I am trying to figure out how to get a list of system processes using Hyperic SIGAR. This is what I have so far:
import org.hyperic.sigar.Humidor;
import org.hyperic.sigar.ProcExe;
import org.hyperic.sigar.SigarException;
import org.hyperic.sigar.SigarProxy;
public class ProcessReader
{
Humidor h;
public ProcessReader()
{
h = Humidor.getInstance();
}
public void printProcessList()
{
SigarProxy sp = h.getSigar();
try
{
long[] pidList = sp.getProcList();
for(int i=0; i<pidList.length; i++)
{
ProcExe temp = sp.getProcExe(pidList[i]);
String exeName = temp.getName();
System.out.println(pidList[i] + " " + exeName);
}
} catch (SigarException e) {
e.printStackTrace();
}
}
}
However, this just ends up throwing a SIGAR exception after a seemingly-arbitrary number of iterations. For example, once, I got this:
1313 /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/bin/java
1311 /System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Versions/A/Support/mdworker
and then it threw a Sigar Exception for an invalid argument at the line:
ProcExe temp = sp.getProcExe(pidList[i]);
Sometimes, it runs for more than two iterations. Sometimes, it runs for less than two iterations. I'm not quite sure what's going on, and the SIGAR documentation doesn't seem to be very helpful. When I wanted to access the CPU and RAM usage information, I used a similar method of getting a Humidor, getting a SIGARProxy from it, and then getting the information objects (CPU and Mem, respectively) from the SIGARProxy. However, doing this for the system processes doesn't seem to be working very well. How am I supposed to do this?
You can Check the class "Ps" under the org.hyperic.sigar.cmd package delivered along with the Sigar package. It lists all the processes running on the system.
I am sure you can manipulate it to get the system processes as well. You can filter the output it with these options:
org/hyperic/sigar/cmd/Ps "CredName.User.eq=$USER"
or if you want to search particualr process use this:
org/hyperic/sigar/cmd/Ps "State.Name.eq=sshd"
I am trying to open this file in java and i want to know what i am doing wrong. The in file lies in the same directory as my Java file, but i tried to open this with both netbeans and eclipse and it gave a file not found exception. Can someone help me open this file and read from it. I am really new to java files. Here is the code
import java.util.*;
import java.io.*;
public class Practice
{
public static void main(String[] args)throws IOException
{
FileReader fin = new FileReader("anagrams.in");
BufferedReader br = new BufferedReader(fin);
System.out.println(fin);
String string = "Madam Curie";
String test = "Radium came";
string = string.toLowerCase();
test = test.toLowerCase();
string = string.replaceAll("[^a-zA-Z0-9]+", "");
test = test.replaceAll("[^a-zA-Z0-9]+", "");
char[] array = string.toCharArray();
char[] array2 = test.toCharArray();
boolean flag = false;
HashMap hm = new HashMap();
for(int i = 0; i < array.length; i++)
{
hm.put(array[i], array[i]);
}
for(int i = 0; i < array2.length; i++)
{
if(hm.get(array2[i]) == null || test.length() != string.length())
{
flag = false;
i = array2.length;
}
else
{
flag = true;
}
}
System.out.println(flag);
}
}
A few tips:
Abide to proper code indentation
If you're using an IDE like Eclipse, it can automatically correct indentation for you
Develop debugging instinct
Try to get what the current working directory is, and list all the files in it
Refactor repetitive code
Writing paired statements like you did should immediately raise red flags
Effective Java 2nd Edition
Item 23: Don't use raw types in new code
Item 52: Refer to objects by their interfaces
Item 46: Prefer for-each loops to traditional for loops
Use sensible variable names
With regards to 2, try something like this:
public static void listDir() {
File current = new File(".");
System.out.println(current.getAbsolutePath());
for (String filename : current.list()) {
System.out.println(filename);
}
}
Then in your main, simply call listDir before everything else, and see if you're running the app from the right directory, and if there's a "anagrams.in" in the directory. Note that some platforms are case-sensitive.
With regards to 3 and 4, consider having a helper method like this:
static Set<Character> usedCharactersIn(String s) {
Set<Character> set = new HashSet<Character>();
for (char ch : s.toLowerCase().toCharArray()) {
set.add(ch);
}
return set;
}
Note how Set<E> is used instead of Map<K,V>. Looking at the rest of the code, you didn't seem to actually need a mapping, but rather a set of some sort (but more on that later).
You can then have something like this in main, which makes the logic very readable:
String s1 = ...;
String s2 = ...;
boolean isNotQuiteAnagram = (s1.length() == s2.length()) &&
usedCharactersIn(s1).containsAll(usedCharactersIn(s2));
Note how variables are now named rather sensibly, highlighting their roles. Note also that this logic does not quite determine that s1 is an anagram of s2 (consider e.g. "abb" and "aab"), but this is in fact what you were doing.
Since this looks like homework, I'll leave it up to you to try to figure out when two strings are anagrams.
See also
Java Coding Conventions
Java Language Guide/For-each loop
Java Tutorials/Collections Framework
Related questions
Why doesn't Java Map extends Collection?
Make sure that the file lies in the same directory as your .class file. It doesn't matter if it is in the same as your .java file or not.
Other than that, the only problem I can see is in your indentation, which doesn't matter.
The normal practice is to put resources in the runtime classpath or to add its path to the runtime classpath so that you can get it by the classloader. Using relative paths in Java IO is considered poor practice since it breaks portability. The relative path would be dependent on the current working directory over which you have totally no control from inside the Java code.
After having placed it in the classpath (assuming that it's in the same folder as the Java class itself), just do so:
BufferedReader reader = null;
try {
InputStream input = Practice.class.getResourceAsStream("anagrams.in");
reader = new BufferedReader(new InputStreamReader(input, "UTF-8")); // Or whatever encoding it is in.
// Process it.
// ...
} finally {
if (reader != null) try { reader.close(); } catch (IOException ignore) {}
}
Closing in finally is by the way mandatory to release the lock on the file after reading.
Put the anagrams.in file in the same location as the .class file. Then you will be able to read the file. And this should help you get some links on how to read from files in Java.