I create a program as below to execute a linux (raspbian) command: "omxplayer".
But I don't know why I cannot get output from omxplayer as the time I type it into command line and hit Enter.But the output only show at the end of the video.
So I want to get the output immediately after I type "omxplayer [video_name]" and hit "Enter" in my program.
Just like the command line (terminal) work when I type directly into it in linux.
This is my code:
public class testprog {
public static void main(String args[]) throws IOException {
String in = "";
while(in!="exit")
{
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
in = reader.readLine();
runCommand(in);
}
}
public static void runCommand(String command)
{
String s;
Process p;
try {
System.out.println("run command " + command);
p = Runtime.getRuntime().exec(new String[]{"bash", "-c",command});
MyInputStreamReader reader1 = new MyInputStreamReader(p.getInputStream());
reader1.setTag("in");
reader1.start();
MyInputStreamReader reader2 = new MyInputStreamReader(p.getErrorStream());
reader2.setTag("in");
reader2.start();
p.waitFor();
System.out.println ("exit: " + p.exitValue());
p.destroy();
} catch (Exception e) {}
}
}
class MyInputStreamReader extends Thread{
boolean isStop = false;
ReadEventHandler handler;
String tag;
InputStream in;
public MyInputStreamReader(InputStream in)
{
this.in = in;
}
public void setHandler(ReadEventHandler handler) {
this.handler = handler;
}
public void setTag(String tag)
{
this.tag = tag;
}
public void run()
{
byte[] buff = new byte[8192];
while (true) {
//String line;
try {
int len = in.read(buff);
if (len == -1)
{
return;
}
String line = new String(buff, 0, len);
if (handler!=null)
handler.onReceived(line);
System.out.println(tag +" " + line);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void dispose()
{
this.isStop = true;
}
public interface ReadEventHandler
{
void onReceived(String line);
}
}
Any response is highly appreciated. Thanks
Did you checked this?
http://javedmandary.blogspot.com/2014/01/firing-up-raspberry-pi-omxplayer-using.html
I guess there is the code you're looking for.
Related
I'm making code for a Server that has multiple clients that joins in it. Here's what the server's looks like.
public class Server {
private final ServerSocket serverSocket;
private static final int PORT = 9000;
private WaitingRoom wroom = new WaitingRoom();
public Server(ServerSocket serverSocket) {
this.serverSocket = serverSocket;
}
public void startServer() throws InterruptedException,Exception{
try {
int count = 0;
while (!serverSocket.isClosed()) {
Socket socket = serverSocket.accept();
System.out.println("A new client has connected!");
ClientHandler clientHandler = new ClientHandler(new Player(count),socket);
Thread thread = new Thread(clientHandler);
thread.start();
count++;
System.out.println(clientHandler.getPlayer().getNickname());
wroom.join(clientHandler.getPlayer());
}
} catch (IOException e) {
closeServerSocket();
}
}
public void closeServerSocket() {
try {
if(serverSocket != null)
serverSocket.close();
}catch (IOException e){
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException,InterruptedException,Exception{
ServerSocket serverSocket = new ServerSocket(PORT);
Server server = new Server(serverSocket);
server.startServer();
}
}
I've a class named ClientHandler that manages these clients in a thread for each, and i pass it also in the Player class because i will use it for things like: Send msg, Receive msg. That's the ClientHandler class:
public class ClientHandler implements Runnable {
public static ArrayList<ClientHandler> clientHandlers = new ArrayList<>();
private Player player;
private String nickname;
private Socket socket;
private BufferedReader bufferedReader;
private BufferedWriter bufferedWriter;
public ClientHandler(Player player,Socket socket) throws InterruptedException,Exception{
try {
this.socket = socket;
this.bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
this.bufferedWriter= new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
nickname = this.bufferedReader.readLine();
player.init(nickname, this);
clientHandlers.add(this);
broadcastMessage("SERVER: " + nickname + " è entrato");
} catch (IOException e) {
closeEverything(socket, bufferedReader, bufferedWriter);
}
}
public Player getPlayer(){
return player;
}
public BufferedWriter getBufferedWriter(){
return bufferedWriter;
}
public BufferedReader getBufferedReader(){
return bufferedReader;
}
#Override
public void run() {
String messageFromClient;
while (socket.isConnected()) {
/* try {
// messageFromClient = bufferedReader.readLine();
} catch (IOException e) {
closeEverything(socket, bufferedReader, bufferedWriter);
break;
} */
}
}
public void broadcastMessage(String messageToSend) {
for (ClientHandler clientHandler : clientHandlers) {
try {
if (!clientHandler.nickname.equals(nickname)) {
clientHandler.bufferedWriter.write(messageToSend);
clientHandler.bufferedWriter.newLine();
clientHandler.bufferedWriter.flush();
}
} catch (IOException e) {
closeEverything(socket, bufferedReader, bufferedWriter);
}
}
}
private void writeToClient(String text) throws IOException{
bufferedWriter.write(text);
bufferedWriter.newLine();
bufferedWriter.flush();
}
public void removeClientHandler() {
clientHandlers.remove(this);
broadcastMessage("SERVER: " + nickname + " è uscito");
}
public void closeEverything(Socket socket, BufferedReader bufferedReader, BufferedWriter bufferedWriter) {
removeClientHandler();
try {
if (bufferedReader != null) {
bufferedReader.close();
}
if (bufferedWriter != null) {
bufferedWriter.close();
}
if (socket != null) {
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Now, the problem is: if I want to create a class named "WaitingRoom" for let players to waint until the wait's done. Where and how could I instantiate it? Before the linked code, i was instantiating it in the ClientHandler, but it worked only for a client a time. Here's what i wrote for the WaitingRoom class:
public class WaitingRoom {
private final int MAXPLAYERS = 2;
private ArrayList<Player> players = new ArrayList<Player>();
public ArrayList<Player> getPlayers(){
return players;
}
public void join(Player player) throws IOException,InterruptedException,Exception{
while(!addPlayer(player)){
player.sendMsg("waiting for join");
TimeUnit.SECONDS.sleep(1);
}
waitStart(player);
}
public boolean addPlayer(Player player){
if (players.size() >= MAXPLAYERS) return false;
players.add(player);
return true;
}
public boolean removePlayer(int idPlayer){
for(Player player : players){
if(player.getId() == idPlayer){
players.remove(player);
return true;
}
}
return false;
}
public void waitStart(Player player) throws IOException,InterruptedException,Exception{
if(players.size() < MAXPLAYERS)
player.sendMsg("sei entrato nella stanza d'attesa");
while(players.size() < MAXPLAYERS){
player.sendMsg("(" + players.size() + "/2) in attesa di giocatori...");
TimeUnit.SECONDS.sleep(1);
}
player.sendMsg("Inizio Gioco");
Player[] players2 = new Player[MAXPLAYERS];
for(int i=0;i<MAXPLAYERS;i++){
players2[0] = new Player(players.get(i).getId()).init(players.get(i).getNickname(),players.get(i).getClientHandler());
}
new Gioco(players2);
cleanRoom();
}
public void cleanRoom(){
players.clear();
}}
it's a really basic concept for waiting room and I only need a place where user must to wait before a gameloop. For example i don't really need multiple wainting rooms, one is ok for me, maybe.
I wrote simple method for reading one file and writing into 2 files. Also I wrote this method with 3 threads, where the first thread reads line-by-line file, the second and the third write readed line into own file. My parallel version of method works in 30 times longer than simple sequential method. Please, help to understand what I do wrong, and how I should do this method to not shooting in my leg)))
private static class Tee {
private BufferedReader reader;
private PrintWriter fWriter;
private PrintWriter sWriter;
volatile boolean done;
String buffer;
volatile int readCount;
volatile int firstWriteCount;
volatile int secondWriteCount;
public Tee(BufferedReader reader, PrintWriter fWriter, PrintWriter sWriter) {
this.reader = reader;
this.fWriter = fWriter;
this.sWriter = sWriter;
}
public void teeWhileInsideCo() throws InterruptedException {
Thread reader = new Thread(new LineReader());
Thread fWriter = new Thread(new LineWriter(this.fWriter, 0));
Thread sWriter = new Thread(new LineWriter(this.sWriter, 1));
reader.start();
fWriter.start();
sWriter.start();
reader.join();
fWriter.join();
sWriter.join();
}
private class LineReader implements Runnable {
#Override
public void run() {
String line;
while (true) {
try {
line = reader.readLine();
} catch (IOException e) {
line = null;
}
while (readCount != firstWriteCount || readCount != secondWriteCount) {
}
if (line == null) {
done = true;
break;
}
buffer = line;
readCount++;
}
}
}
private class LineWriter implements Runnable {
private PrintWriter writer;
private int number;
public LineWriter(PrintWriter writer, int n) {
System.out.println(Tee.this);
this.writer = writer;
this.number = n;
}
#Override
public void run() {
while (true) {
while (!done && ((number == 0 ? firstWriteCount : secondWriteCount) == readCount)) {
}
if (done) {
break;
}
writer.println(buffer);
if (number == 0) {
firstWriteCount++;
} else {
secondWriteCount++;
}
}
writer.flush();
}
}
}
Is it possible to read a text file by running several threads, so that received line contains information about the thread that read this line?
For now, i can read with one thread:
public class Test {
public static void main(String[] args) throws InterruptedException {
Deque<String> deque = new LinkedList<>();
for (int i = 0; i < 4; i++) {
new Thread(new SubReadThread(deque)).start();
}
new Thread(new WriteThread(deque)).start();
}
}
class SubReadThread implements Runnable {
private final Deque<String> deque;
public SubReadThread(Deque<String> deque) {
this.deque = deque;
}
#Override
public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("list.txt"), "UTF8"));
String line = null;
String newLine;
while (true) {
synchronized (deque) {
if (deque.size() < 1) {
line = br.readLine();
newLine = "#" + (Thread.currentThread().getId() - 9) + " " + line;
deque.addLast(newLine);
deque.notify();
} else {
deque.wait();
}
if (line == null) {
break;
}
}
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
class WriteThread implements Runnable {
private final Deque<String> deque;
private List<String> list = new ArrayList<>();
public WriteThread(Deque<String> deque) {
this.deque = deque;
}
#Override
public void run() {
String line;
while (true) {
synchronized (deque) {
if (deque.size() > 0) {
if ((line = deque.pollFirst()).contains("null")) {
break;
} else {
list.add(line);
deque.notifyAll();
}
} else {
try {
deque.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
for(String s : list) {
System.out.println(s);
}
}
}
And expected output something like this:
#3 line1
#1 line2
#4 line3
#2 line4
...............
UPDATE All that was needed to work properly, move BufferedReader to main method and pass its object to the constructor.
I'm using the following code to search specific files in my computer and write the absolute path in a text file. My problem is that every time I run this code it add duplicate lines into text file, i want to add only those lines(file path) which are not written in the text file at that time (no duplicates).. Thank you
public static void walkin(File dir) {
String pattern = ".mp4";
try {
PrintWriter out = new PrintWriter(new BufferedWriter(
new FileWriter("D:\\nawaaaaaa.txt", true)));
File listFile[] = dir.listFiles();
if (listFile != null) {
for (int i = 0; i < listFile.length; i++) {
if (listFile[i].isDirectory()) {
walkin(listFile[i]);
} else if (listFile[i].getName().endsWith(pattern)
&& listFile[i].isFile()) {
System.out.println(listFile[i].getPath());
out.write(listFile[i].toString());
out.write("\r\n");
// out.close();
} else {
walkin(listFile[i]);
}
}
}
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Your code works for me, no idea what is the problem on your side, how you are calling it; but you can optimize your code a bit, something as follows (just very quick code, code be made nicer, but to give you an idea):
public class SomeTest {
private static HashSet<String> filez = new HashSet<String> ();
public static void walkin(File dir, PrintWriter out) {
String pattern = ".mp4";
File listFile[] = dir.listFiles();
if (listFile != null) {
for (int i = 0; i < listFile.length; i++) {
if (listFile[i].getName().endsWith(pattern) && listFile[i].isFile()) {
//System.out.println(listFile[i].getPath());
if (filez.add(listFile[i].getPath())) {
out.write(listFile[i].toString());
out.write("\r\n");
}
} else {
walkin(listFile[i], out);
}
}
}
}
public static void main(String[] args) {
try {
File dir = new File("C:\\mydir");
PrintWriter out = new PrintWriter(new BufferedWriter(
new FileWriter("D:\\nawaaaaaa.txt", true)));
walkin(dir, out);
out.close();
} catch (IOException e) {
//
}
}
}
You can use the filez hashset to print stuff, or write your file at the end of the parsing process as well.. your choice.
If you don't want duplicates in the file, you will need to keep track of the file names you have already written. A HashSet<String> is going for this. But I'm surprised the above code works at all given that you keep opening the file at the top of walkin() and walkin() itself is recursive. You need to rethink your code a bit. Possibly passing the PrintWriter into walkin() as a parameter.
Since you are running the code multiple times ("every time I run this code it add duplicate lines into text file"), so once you finish writing to the file, you read each line and store it in a HashSet<String>. And use another writer to write it to the file.
BufferedWriter writer = new BufferedWriter(new FileWriter("filename"));
for (String eachUniqueLine: `Your hash set`) {
writer.write(eachUniqueLine);
writer.newLine();
}
(It is costly as in you have to do more i/o operation)
You need to expand your method into a class that perform this kind of tasks.
You have two main problem you open a writer for each directory and you call the walkin, for things that do not apply to your logic (and open writer again).
You should try to design a class that will be able to create an index for you.
public static void main(String[] args) throws IOException {
File createTempFile = File.createTempFile("mp4", ".idx");
FileIndexer fi = new FileIndexer(createTempFile.getAbsolutePath());
fi.index("C:\\", "mp4");
System.out.println(createTempFile);
}
public static class FileIndexer {
private static final String END_OF_LINE = "\r\n";
private final String outputPath;
private final Set<String> index = new HashSet<String>();
public FileIndexer(String outputPath) {
this.outputPath = outputPath;
}
private boolean isValidPath(String path) {
return outputPath != null && outputPath.trim().length() > 0;
}
private boolean isValidIndexFile(File file) {
return file.isFile() && file.canRead() && file.canWrite();
}
private void createIndexFile(File file) throws IOException {
if(file.createNewFile() == false) {
throw new IOException("Could not create index file");
}
this.index.clear();
}
private void readIndexFile(File file) throws IOException {
isValidIndexFile(file);
index.clear();
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(new FileReader(file));
String line;
while((line = bufferedReader.readLine()) != null) {
addToIndex(line);
}
} finally {
if(bufferedReader != null) {
bufferedReader.close();
}
}
}
private void addToIndex(String line) {
index.add(line);
}
private PrintWriter openIndex() throws IOException {
if(isValidPath(outputPath) == false) {
throw new IOException(String.format("The outputPath is not valid: [%s]",outputPath));
}
File indexFile = new File(outputPath);
if(indexFile.exists()) {
readIndexFile(indexFile);
} else {
createIndexFile(indexFile);
}
return new PrintWriter(new BufferedWriter(new FileWriter(this.outputPath, true)));
}
public synchronized void index(String pathToIndex, String pattern) throws IOException {
isValidPath(pathToIndex);
PrintWriter out = openIndex();
try {
File elementToIndex = new File(pathToIndex);
index(elementToIndex,pathToIndex, out);
} finally {
if(out != null) {
out.close();
}
}
}
private void index(File elementToIndex, String pattern, PrintWriter out) {
if(elementToIndex == null) {
return;
}
if(elementToIndex.isDirectory()) {
for(File file : elementToIndex.listFiles()) {
index(file,pattern, out);
}
}
if(elementToIndex.isFile() && elementToIndex.getAbsolutePath().endsWith(pattern)) {
writeToIndex(elementToIndex, out);
}
}
private void writeToIndex(File elementToIndex, PrintWriter out) {
out.write(elementToIndex.getAbsolutePath());
out.write(END_OF_LINE);
}
}
Problem Solved (BTW i'm not sure if it is most efficient solution or not ).......
public static void main(String[] args) {
try {
File dir = new File("D:\\To Do");
BufferedWriter out = new BufferedWriter(new FileWriter(
"D:\\path.txt", true));
walkin(dir, out);
out.close();
readfile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // Replace this with a suitable directory
// walkin(new File("D:/to Do"));
}
public static void walkin(File dir, BufferedWriter out) throws IOException {
String pattern = ".mp4";
// BufferedWriter out = new BufferedWriter(
// new FileWriter("D:\\path.txt",true));
File listFile[] = dir.listFiles();
if (listFile != null) {
for (int i = 0; i < listFile.length; i++) {
if (listFile[i].getName().endsWith(pattern)
&& listFile[i].isFile()) {
if (filez.add(listFile[i].getPath())) {
// System.out.println(listFile[i].getPath());
out.write(listFile[i].toString());
out.write("\r\n");
// System.out.println(filez);
}
} else {
walkin(listFile[i], out);
}
}
}
}
public static void readfile() {
BufferedReader br = null;
String str;
try {
BufferedWriter out = new BufferedWriter(new FileWriter(
"D:\\duplicate_free.txt"));
br = new BufferedReader(new FileReader("D:\\path.txt"));
while ((str = br.readLine()) != null) {
if (files.contains(str)) {
} else {
files.add(str);
}
}
for (String uniq : files) {
out.write(uniq);
System.out.println(uniq);
}
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I am sending a text message to mobile number. I write the data using a o/p stream and read the data using i/p stream from Port. The o/p stream is working properly, but I can not read the data from the i/p stream. Here is my code:
public class SendMsg implements SerialPortEventListener
{
Enumeration portList;
CommPortIdentifier portId;
SerialPort serialPort;
OutputStream outputStream;
InputStream inputStream;
Thread readThread;
String messageString;
String messageString1;
String strResponse="";
SendMsg pWriter;
String msg[]=new String[200];
int ix=0;
boolean msgEnd=true;
String className;
static Enumeration ports;
static CommPortIdentifier pID;
static String messageToSend = "ComPortSendMsg deatails!\n";
public SendMsg(String className) throws NoSuchPortException, IOException
{
this.className=className;
ports = CommPortIdentifier.getPortIdentifiers();
System.out.println("ports name"+ports);
while(ports.hasMoreElements())
{
pID = (CommPortIdentifier)ports.nextElement();
System.out.println("Port Name " + pID.getName());
if (pID.getPortType() == CommPortIdentifier.PORT_SERIAL)
{
System.out.println("Port Name 1 " + pID.getName());
if (pID.getName().equals("COM1"))
{
try {
System.out.println("Port Name 2 " + pID.getName());
System.out.println("COM1 found");
serialPort=(SerialPort)pID.open(className, 9600);
outputStream=serialPort.getOutputStream();
inputStream=serialPort.getInputStream();
break;
} catch (PortInUseException ex) {
Logger.getLogger(SendMsg.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}
public void closePort()
{
try
{
inputStream.close();
System.out.println("Finished2");
outputStream.close();
System.out.println("Finished1");
serialPort.close();
System.out.println("Finished");
}
catch(Exception e)
{
System.out.println("Close Error"+e);
}
}
public void send(String phno,String msg)
{
String s = "AT+CMGF="+1;
System.out.println("AT+CMGF command :"+s);
messageString = "AT+CMGS=\""+phno+"\"\r";
messageString1 = msg+"\n" +(char)26;
System.out.println("AT CMGS "+messageString);
System.out.println("AT CMGS "+messageString1);
try
{
outputStream.write(s.getBytes());
System.out.print("this is send try block");
outputStream.write(messageString.getBytes());
outputStream.write(messageString1.getBytes());
Thread.sleep(2000);
byte[] b = new byte[1000];
String r="";
String r1="";
System.out.println(inputStream.available());
while (inputStream.available() > 0) {
int n = inputStream.read(b);
System.out.println("number of bytes"+n);
r= new String(b);
}
System.out.println("this is input stream msg"+r);
}
catch (Exception e)
{
System.out.println(e);
}
}
public static void main(String args[]) throws NoSuchPortException, IOException
{
SendMsg f=new SendMsg("Msg Sending");
f.send("9884345649","Wish U Happy");
System.out.println("---------END--------");
f.closePort();
}
#Override
public void serialEvent(SerialPortEvent spe) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
You should be reading the InputStream from within the serialEvent(..) method.
Something like this:
public void serialEvent(SerialPortEvent spe) {
int data;
String r;
try
{
int len = 0;
while ( ( data = in.read()) > -1 )
{
buffer[len++] = (byte) data;
}
r = new String(buffer,0,len);
System.out.println("this is input stream msg"+r);
}
catch ( IOException e )
{
e.printStackTrace();
System.exit(-1);
}
}
Secondly, you can put in a long sleep, e.g. Thread.sleep(100000);, in the main method, before
calling f.closePort();.
Or, potentially the serialEvent(..) method could close the port after receiving the inputStream's data.
Hope this helps!