I'm writing an small application like IDM in java.
But this has has many Exceptions.
This is the code of Downloader class which implements runnable and I want use it for multithreading.
public class Downloader implements Runnable{
private DataInputStream inputStream;
private byte[][] fileData;
private int index;
private int size;
public Downloader(DataInputStream inputStream, byte[][] fileData, int index, int size) {
this.inputStream = inputStream;
this.fileData = fileData;
this.index = index;
this.size = size;
}
public synchronized void run() {
try{
inputStream.skipBytes(index * size);
for(int i= 0;i<size;i++){
fileData[index][i] = inputStream.readByte();
System.out.println("It works : " + index);
}
}
catch(Exception e){
System.out.println(e.getMessage());
}
}}
and this is my main class
public class Main {
public static void main(String[] args) {
String s;
//Scanner input = new Scanner(System.in);
//System.out.print("Enter file destination : ");
//s = input.nextLine();
s = "http://video.varzesh3.com/video/clip1/92/uclip/fun/gaf_6_borhani.mp4";
URL url;
URLConnection connection;
DataInputStream inputStream;
FileOutputStream outStream;
byte[][] fileData;
try{
url = new URL(s);
connection = url.openConnection();
inputStream = new DataInputStream(connection.getInputStream());
fileData = new byte[8][connection.getContentLength() / 4];
int size = connection.getContentLength() / 4;
Runnable d0 = new Downloader(inputStream, fileData, 0, size);
Runnable d1 = new Downloader(inputStream, fileData, 1, size);
Runnable d2 = new Downloader(inputStream, fileData, 2, size);
Runnable d3 = new Downloader(inputStream, fileData, 3, size);
Thread thread0 = new Thread(d0);
Thread thread1 = new Thread(d1);
Thread thread2 = new Thread(d2);
Thread thread3 = new Thread(d3);
thread0.start();
thread1.start();
thread2.start();
thread3.start();
inputStream.close();
String path = "C:\\Users\\NetTest\\Desktop\\test.mp4";
outStream = new FileOutputStream(new File(path));
outStream.write(fileData[0]);
/*outStream.write(fileData[1]);
outStream.write(fileData[2]);
outStream.write(fileData[3]);
outStream.write(fileData[4]);
outStream.write(fileData[5]);
outStream.write(fileData[6]);
outStream.write(fileData[7]);*/
outStream.close();
}
catch(Exception e){
System.out.println(e.getMessage());
}
}}
but when I run it this happens
It works: 0
null
null
null
null
What should I do now?
There are 2 Problems in your code.
At the current state you close() the InputStream from which all Thread try to read directly after you started them (-> while they are running). To solve this Problem you can call the join() Method of the Thread class. In your case your'd have to call it for all 4 Threads to make sure they are finished.
If I understand it correctly you want to seperate the download File into 4 parts downloading at the same time.
To do this you need 4 independent InputStreams. (Currently you are using ONE [See also: Java Object Copying])
So to change this your code would look something like this:
public class Downloader implements Runnable{
private byte[][] fileData;
private int index;
private int size;
private URL url;
public Downloader(URL url, byte[][] fileData, int index, int size) {
this.fileData = fileData;
this.index = index;
this.size = size;
this.url = url;
}
public synchronized void run() {
try{
URLConnection connection = url.openConnection();
DataInputStream inputStream = new DataInputStream(connection.getInputStream());
inputStream.skipBytes(index * size);
for(int i= 0;i<size;i++){
fileData[index][i] = inputStream.readByte();
System.out.println("It works : " + index);
}
}catch(Exception e){
System.out.println(e.getMessage());
}
}
}
Related
I have some problems with the connection between my EV3 and my Android-Device.
I am able to receive Data with my EV3, but I can't send.
I have signed up with my Github account if you like to see the App.
Here is my Code:
public class Bluetooth {
public static int speed = 100;
public static BTConnector connector;
public static NXTConnection connection;
public static void main(String[] args) throws IOException {
openConnection();
Thread moveWithBluetoothThread = new Thread(new moveWithBluetooth());
moveWithBluetoothThread.start();
}
public static void openConnection() {
connector = new BTConnector();
LCD.drawString("Waiting for Connecrion", 3, 1);
connection = connector.waitForConnection(0, NXTConnection.RAW);
LCD.clear();
LCD.drawString("Connected", 3, 5);
}
}
class moveWithBluetooth implements Runnable {
#Override
public void run() {
while (true) {
InputStream is = Bluetooth.connection.openInputStream();
BufferedReader dis = new BufferedReader(new InputStreamReader(is), 1);
OutputStream os = Bluetooth.connection.openOutputStream();
BufferedWriter dos = new BufferedWriter(new OutputStreamWriter(os), 1);
try {
byte[] b;
for (int i = 0; i < 100; i++) {
String n = dis.readLine();
System.out.println(n);
b = n.getBytes();
Bluetooth.connection.write(b, b.length);
Thread.sleep(10);
dos.write(n);
dos.flush();
}
dis.close();
dos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
I found out, that there was no Problem with my EV3. That means, you can use this code. If you are having the same Problem, here is my solution:
The Problem was the Library I use in my Application. At the "Tssues"-Tab of Github was my Problem. The library waits until there is a complete Transmission, but the EV3 sends a permanent Stream, so I just had to add \r\n at the end of my Transmission. My final Code looked like that:
byte[] b = (n + "\r\n").getBytes();
Bluetooth.connection.write(b, b.length);
I was trying to make a java program to copy a file with the reader in one thread and the writer in another thread. The program works without showing any errors but the copied file has a different checksum from the original file. I am not able to find the mistake i made in the program. The program copies text files and they dont seem to be having any problems. When i try copying a zip file, copying finishes successfully, but when i try to extract the copied zip, it shows that the zip file is corrupted. Can someone help me in finding the mistake.
import java.io.*;
import java.util.concurrent.*;
import java.util.*;
class qu{
qu(byte[] b,int s){
this.b=b;
this.s=s;
}
byte[] b;
int s;
public String toString(){
return s+"";
}
}
class reader implements Runnable{
public byte[] b = new byte[1048576];
String inf;
int s;
long max;
private BlockingQueue<qu> blockingQueue;
public reader(String inf,BlockingQueue<qu> blockingQueue,long max){
this.inf=inf;
this.max=max;
this.blockingQueue=blockingQueue;
}
public void run(){
RandomAccessFile in=null;
try{
in = new RandomAccessFile(inf,"rw");
while((s=in.read(b))!=-1){
blockingQueue.put(new qu(b,s));
}
}catch(Exception e){System.out.println(e);}
finally{
try{
in.close();
}catch(Exception e){System.out.println(e);}
}
}
}
class writer implements Runnable{
public byte[] b = new byte[1048576];
String outf;
int s=0;
long max=0;
private BlockingQueue<qu> blockingQueue;
public writer(String outf,BlockingQueue<qu> blockingQueue,long max){
this.outf=outf;
this.max=max;
this.blockingQueue=blockingQueue;
}
public void run(){
RandomAccessFile out;
qu asd;
System.out.println("Copying..");
try{
out = new RandomAccessFile(outf,"rw");
while(out.getFilePointer()!=max){
asd=blockingQueue.take();
//System.out.println(new String(asd.b));
out.write(asd.b,0,asd.s);
}
out.close();
}catch(Exception e){System.out.println(e);}
}
}
class mul {
public static void main(String[] args) {
String inf = args[0];
String outf = args[1];
File file =new File(inf);
long max = file.length();
BlockingQueue<qu> blockingQueue = new ArrayBlockingQueue<>(64);
if(file.exists()){
long start_time = System.nanoTime();
Thread t1=new Thread(new reader(inf,blockingQueue,max));
t1.start();
Thread t2=new Thread(new writer(outf,blockingQueue,max));
t2.start();
try{
t1.join();
t2.join();
}catch(Exception ex){System.out.println(ex);}
long end_time = System.nanoTime();
double difference = (end_time - start_time) / 1e6;
System.out.println("Time taken: "+difference+"ms");
System.out.println("Copy Completed..");
}else{System.out.println("File not Found");}
}
}
You need to copy your byte array e.g.
public class Qu {
private final byte[] b;
private final int s;
public Qu(byte[] b,int s) {
this.b = Arrays.copyOf(b, b.length);
this.s = s;
}
public String toString(){
return s+"";
}
}
In my servlet I am running a few command line commands in background, I've successfully printed output on console.
My doGet()
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
String[] command =
{
"zsh"
};
Process p = Runtime.getRuntime().exec(command);
new Thread(new SyncPipe(p.getErrorStream(), response.getOutputStream())).start();
new Thread(new SyncPipe(p.getInputStream(), response.getOutputStream())).start();
PrintWriter stdin = new PrintWriter(p.getOutputStream());
stdin.println("source ./taxenv/bin/activate");
stdin.println("python runner.py");
stdin.close();
int returnCode = 0;
try {
returnCode = p.waitFor();
}
catch (InterruptedException e) {
e.printStackTrace();
} System.out.println("Return code = " + returnCode);
}
class SyncPipe implements Runnable
{
public SyncPipe(InputStream istrm, OutputStream ostrm) {
istrm_ = istrm;
ostrm_ = ostrm;
}
public void run() {
try
{
final byte[] buffer = new byte[1024];
for (#SuppressWarnings("unused")
int length = 0; (length = istrm_.read(buffer)) != -1; )
{
// ostrm_.write(buffer, 0, length);
((PrintStream) ostrm_).println();
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
private final OutputStream ostrm_;
private final InputStream istrm_;
}
Now, I want to save the ostrm_ to a string or list, and use that inside doGet()
How to achieve this?
==============================EDIT============================
Based on answers below, I've edited my code as follows
int length = 0; (length = istrm_.read(buffer)) != -1; )
{
// ostrm_.write(buffer, 0, length);
String str = IOUtils.toString(istrm_, "UTF-8");
//((PrintStream) ostrm_).println();
System.out.println(str);
}
Now, How do I get the str in runnable class into my doGet()?
You can use Apache Commons IO.
Here is the documentation of IOUtils.toString() from their javadocs
Gets the contents of an InputStream as a String using the specified character encoding. This
method buffers the input internally, so there is no need to use a
BufferedInputStream.
Parameters: input - the InputStream to read from encoding - the
encoding to use, null means platform default Returns: the requested
String Throws: NullPointerException - if the input is null IOException
- if an I/O error occurs
Example Usage:
String str = IOUtils.toString(yourInputStream, "UTF-8");
You can call something like the following:
(EDIT: added also the client calls)
public void run() {
try
{
String out = getAsString(istrm_);
((PrintStream) ostrm_).println(out);
} catch (Exception e) {
e.printStackTrace();
}
}
public static String getAsString(InputStream is) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int cur = -1;
while((cur = is.read()) != -1 ){
baos.write(cur);
}
return getAsString(baos.toByteArray());
}
public static String getAsString(byte[] arr) throws Exception {
String res = "";
for(byte b : arr){
res+=(char)b;
}
return res;
}
public class ServerPipelineFactory implements ChannelPipelineFactory {
#Override
public ChannelPipeline getPipeline() throws Exception {
PacketFrameDecoder decoder = new PacketFrameDecoder();
PacketFrameEncoder encoder = new PacketFrameEncoder();
return Channels.pipeline(decoder, encoder, new Handler());
}
}
and my decoder
public class PacketFrameDecoder extends
ReplayingDecoder<PacketFrameDecoder.DecoderState> {
public enum DecoderState {
READ_CONTENT;
}
private int length;
public PacketFrameDecoder() {
super(DecoderState.READ_CONTENT);
}
#Override
protected Object decode(ChannelHandlerContext chc, Channel chnl,
ChannelBuffer cb, DecoderState state) throws Exception {
switch (state) {
case READ_CONTENT:
for (int i = 0; i < cb.capacity(); i ++) {
byte b = cb.getByte(i);
System.out.println((char) b);
}
return null;
default:
throw new Error("Shouldn't reach here.");
}
}
}
and I send messages
Socket fromserver = new Socket("localhost", 7283);
PrintWriter out = new PrintWriter(fromserver.getOutputStream(), true);
int data = 12;
out.write(data);
out.flush();
out.close();
fromserver.close();
but when I get bytes- I have cb.capacity() = 256
and message "?0?0" System.out.println((char) b);
please help
Using capacity is wrong a it is the "max" amount of bytes in the buffer. Also starting at position 0 is wrong as the readerIndex could be on an other position. Please read the apidocs of ChannelBuffer which all of this explains in great detail.
I'm receiving a file that I want to save to disc, this has the highest priority. But I want to "split"/"share" this stream with two other operations.
My approach has so far been to have a MainStream that can create subStreams that reads from a buffer in the MainStream.
If this is a suitable approach I need some way to determine where in the stream the subStreams are. How can I do that? Or is it a better way to solve my main problem?
If I/O is not you bottle neck, you can use multi-thread write file.
The code below is just an example:
/**
* #author lichengwu
* #version 1.0
* #created 2013-01-08 12:11 AM
*/
public class MultiWrite {
private static final int SIZE = 1024 * 1024 * 1024;
ExecutorService exec = Executors.newFixedThreadPool(5);
public void start() {
final File source = new File("");
long size = source.length();
final File store = new File("");
for (long position = 0; position < size; position = position + SIZE) {
exec.execute(new WriteTask(source, store, position));
}
}
public class WriteTask implements Runnable {
private final File store;
private final File source;
private final long position;
public WriteTask(File source, File store, long position) {
this.store = store;
this.position = position;
this.source = source;
}
public void run() {
try {
RandomAccessFile in = new RandomAccessFile(source, "r");
// lock part of store
RandomAccessFile out = new RandomAccessFile(store, "rw");
FileChannel channel = out.getChannel();
FileLock lock;
while (true) {
try {
lock = channel.tryLock(position, SIZE, false);
break;
} catch (Exception e) {
// deal with
}
}
out.seek(position);
in.seek(position);
byte[] data = new byte[SIZE];
in.read(data);
out.write(data);
// release
lock.release();
channel.close();
out.close();
in.close();
} catch (IOException e) {
// deal with
}
}
}
}