PipedOutputStream in Java - java

Am trying to write all the prime numbers less than 10000 into a PipedOutPutStream. When I execute the program it prints till 1619. But the the program is still running. If I comment the code for writing into the stream and execute the program then it prints the prime numbers correctly.Can anyone figure out why is this happening ?
public class PrimeThread implements Runnable {
private DataOutputStream os;
public PrimeThread(OutputStream out) {
os = new DataOutputStream(out);
}
#Override
public void run() {
try {
int flag = 0;
for (int i = 2; i < 10000; i++) {
flag = 0;
for (int j = 2; j < i / 2; j++) {
if (i % j == 0) {
flag = 1;
break;
}
}
if (flag == 0) {
System.out.println(i);
os.writeInt(i);//if i comment this line its printing all the primeno
os.flush();
}
}
os.writeInt(-1);
os.flush();
os.close();
} catch (IOException iOException) {
System.out.println(iOException.getMessage());
}
}
}
public class Main {
public static void main(String[] args) {
PipedOutputStream po1 = new PipedOutputStream();
//PipedOutputStream po2 = new PipedOutputStream();
PipedInputStream pi1 = null;
//PipedInputStream pi2 = null;
try {
pi1 = new PipedInputStream(po1);
//pi2 = new PipedInputStream(po2);
} catch (IOException iOException) {
System.out.println(iOException.getMessage());
}
Runnable prime = new PrimeThread(po1);
Thread t1 = new Thread(prime, "Prime");
t1.start();
//some code
}
}

PipedOutPutStream's internal buffer is overflowed and cannot accept more data until it is dumped. In the main thread, read from PipedInputStream pi1, and prime number calculation would go on.

Related

Java - Comparing two huge text files

I am trying to develop a basic java program to compare two huge text files and print non matching records .i.e. similar to minus function in SQL. but I am not getting the expected results because all the records are getting printed even though both files are same. Also suggest me whether this approach is performance efficient for comparing two huge text files.
import java.io.*;
public class CompareTwoFiles {
static int count1 = 0 ;
static int count2 = 0 ;
static String arrayLines1[] = new String[countLines("\\Files_Comparison\\File1.txt")];
static String arrayLines2[] = new String[countLines("\\Files_Comparison\\File2.txt")];
public static void main(String args[]){
findDifference("\\Files_Comparison\\File1.txt","\\Files_Comparison\\File2.txt");
displayRecords();
}
public static int countLines(String File){
int lineCount = 0;
try {
BufferedReader br = new BufferedReader(new FileReader(File));
while ((br.readLine()) != null) {
lineCount++;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return lineCount;
}
public static void findDifference(String File1, String File2){
String contents1 = null;
String contents2 = null;
try
{
FileReader file1 = new FileReader(File1);
FileReader file2 = new FileReader(File2);
BufferedReader buf1 = new BufferedReader(file1);
BufferedReader buf2 = new BufferedReader(file2);
while ((contents1 = buf1.readLine()) != null)
{
arrayLines1[count1] = contents1 ;
count1++;
}
while ((contents2 = buf2.readLine()) != null)
{
arrayLines2[count2] = contents2 ;
count2++;
}
}catch (Exception e){
e.printStackTrace();
}
}
public static void displayRecords() {
for (int i = 0 ; i < arrayLines1.length ; i++) {
String a = arrayLines1[i];
for (int j = 0; j < arrayLines2.length; j++){
String b = arrayLines2[j];
boolean result = a.contains(b);
if(result == false){
System.out.println(a);
}
}
}
}
}
Based upon your explanation you do not need embedded loops
consider
public static void displayRecords() {
for (int i = 0 ; i < arrayLines1.length && i < arrayLines2.length; i++)
{
String a = arrayLines1[i];
String b = arrayLines2[i];
if(!a.contains(b){
System.out.println(a);
}
}
For the performance wise, you should try to match the size of the files. If the sizes(in bytes) are exactly the same, you might not need to compare them.

Why doesn't a socket send the last message unless there is a delay before it?

Alright so I am looking at this piece of code that is supposed to get an array of bytes which represents an image and send it piece by piece to a server. The server needs to be told when the image transmission is done, this ending message is "CLOSE". Everything works fine but unless I uncomment Thread.sleep the end message isn't sent. Also the delay needs to be quite big for some reason, 100 ms for example doesn't work. If anyone could provide an explanation for this behaviour I would be grateful since I don't have a very good understanding of java.
private class NetTask extends AsyncTask<Void, Void, Void>
{
private String ip;
private byte[] to_send;
public NetTask(String ip, byte[] to_send)
{
this.ip = ip;
this.to_send = to_send;
}
#Override
protected Void doInBackground(Void...params)
{
try {
Log.i(dTag, "" + to_send.length);
Socket sck = new Socket(ip, 1234);
DataOutputStream dOut = new DataOutputStream(sck.getOutputStream());
dOut.write(ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(to_send.length).array());
Log.d(dTag, "" + to_send.length);
int x = 500;
int len = to_send.length;
for (int i = 0; i < len - x + 1; i += x)
dOut.write(Arrays.copyOfRange(to_send, i, i + x));
if (len % x != 0)
dOut.write(Arrays.copyOfRange(to_send, len - len % x, len));
/*try {
Thread.sleep(1000);
}
catch (Exception ex) {
Log.d(dTag, "thread sleep error");
}*/
dOut.write("CLOSE".getBytes());
dOut.flush();
dOut.close();
sck.close();
}
catch (IOException ex) {
Log.d(dTag, ex.getMessage());
}
return null;
}
}
The server is in c#, here is the code:
while (ok)
{
sck.Listen(1000);
Socket accepted = sck.Accept();
buffer = new byte[accepted.SendBufferSize];
int bytesRead = -1;
bool reading = true;
int im_size = -1;
int index = 0;
byte[] image = null;
while (reading)
{
bytesRead = accepted.Receive(buffer);
if (bytesRead == 5)
Console.WriteLine(bytesRead);
string strData = "YADA";
byte[] formatted = new byte[bytesRead];
if (bytesRead == 5)
{
for (int i = 0; i < bytesRead; i++)
{
formatted[i] = buffer[i];
}
strData = Encoding.ASCII.GetString(formatted);
}
if (strData == "CLOSE")
{
Console.WriteLine("GOT CLOSE MESSAGE");
Image im = Image.FromStream(new MemoryStream(image));
im.Save(#"D:\im1.bmp");
}
else
{
if (im_size == -1)
{
im_size = BitConverter.ToInt32(buffer, 0);
image = new byte[im_size];
Console.WriteLine(im_size);
}
else
{
for (int i = 0; i < bytesRead && index < im_size; i++)
{
image[index++] = buffer[i];
}
}
}
}
accepted.Close();
}

Java outputting to text file?

So I am having troubles printing to output. I understand the concept, but when it comes to this problem its kinda weird. I've tried different print lines and all of them give me different results from the console window. I'm still trying different things, but im starting to run out of ideas. Thanks and much appreciated !
This is what I want the expected output to be.
1
1, 2, 3, 4
When I try println it does this for output.println(data[0]);
1
, 2, 3, 4
when I do a regular print it does this
1, 2, 3, 4
This is the text file print method`
public class JavaApplication1 {
static int[] Array(int[] data) {
int size = 1;
if (data !=null) {
size = 1 +data.length;
}
return new int [size];
}
private static int[] addToArray(int[] data, int x) {
int[] array2 = Array(data);
if(data !=null) {
System.arraycopy(data,0,array2,0,data.length);
}
array2[array2.length - 1] = x;
return array2;
}
private int[] data;
public JavaApplication1 (int[] data, int x) {
this.data = addToArray(data, x);
}
public void printall() {
System.out.print(data[0]);
for (int i = 1; i < data.length; i++) {
System.out.printf(", %d", data[i]);
}
System.out.println();
} public void text() {
try {
PrintWriter output = new PrintWriter("test.txt");
output.print(data[0]);
for (int i = 1; i < data.length; i++) {
output.printf( ", %d", data[i]);
output.flush();
}
} catch (Exception ex) {
}
}
public static void main(String[] args) {
int[] in = {1,2,3};
int[] test = {1,2,3};
int l = 4;
int x = 4;
JavaApplication1 a = new JavaApplication1(null, 1);
a.printall();
JavaApplication1 b = new JavaApplication1(in, x);
b.printall();
JavaApplication1 c = new JavaApplication1(null, 1);
c.text();
JavaApplication1 d = new JavaApplication1(test, l);
d.text();
}
}
Try this :
public void text() {
try {
PrintWriter output = new PrintWriter("test.txt");
output.println(data[0]);
for (int i = 0; i < data.length; i++) {
if (i != (data.length - 1)) {
output.printf("%d, ", data[i]);
} else {
output.printf("%d", data[i]);
}
output.flush();
}
} catch (Exception ex) {
}
}
To make it a new line for each output loop it and add "\n" to each line you write or you can convert to string and edit String format to whatever you want. You can add a comma if you want
string.format()
try do in this way
public void text() {
try {
PrintWriter output = new PrintWriter("test.txt");
for (int i = 0; i < data.length; i++) {
if(i > 0){
output.print(",");
}
output.print(data[i]);
output.flush();
}
} catch (Exception ex) {
}
}
Try this:
PrintWriter output = new PrintWriter("test.txt");
output.println(data[0]); //this is where you call the println
for (int i = 0; i < data.length; i++) {
output.printf( ", %d", data[i]);
output.flush();
}
Cause of problem: In your code, everytime you call text(), you are replacing existing file, without updating or appending new data to it.
Refer this SO question. You can write printWriter as
PrintWriter output = new PrintWriter(new BufferedWriter(new FileWriter("test.txt", true)));
I have tested on local, Try this code.
public void text() {
try {
// Adding data to existing file without replacing it.
PrintWriter output = new PrintWriter(new BufferedWriter(new FileWriter("test.txt", true)));
output.print(data[0]);
for (int i = 1; i < data.length; i++) {
output.printf(", %d", data[i]);
}
output.print("\n"); // Added next line in the file
output.flush();
output.close(); // closing PrintWriter.
} catch (Exception ex) {
// log your exception.
}
}

java thread waiting for input on comport blocks other thread as well

I've got a main program that starts two threads. First I only had this thread, that executes the following inside the while(true):
loopCounter++;
outputStream.write(pollBuf);
readResponse();
Thread.sleep(200);
outputStream.write(statusBuf);
readResponse();
logger.info("status executed");
The problem is that when the second readResponse doesn't return because the device listening to the comport simply doesn't answer I'm stuck and the display that gives the status of the machine simply still shows "running" instead of software error or something alike.
So I need to know when this thread is stuck and therefore I added another thread that now gets created and started in the main program right before the other thread, the code inside the while(true) of the run() method of this second thread:
public class StatusThread implements Runnable {
static Logger logger = Logger.getLogger(StatusThread.class);
private Nv10ToVcdm mainProgram;
public void initialize(Nv10ToVcdm mProgram, boolean acceptBills) {
mainProgram = mProgram;
}
public void run() {
int loopCounter = mainProgram.getLoopCounter();
while (true) {
try {
Thread.sleep(1000);
int currentLoopCounter = mainProgram.getLoopCounter();
if (loopCounter != currentLoopCounter) {
loopCounter = currentLoopCounter;
} else {
mainProgram.writeToDisplay("SOFTWARE", "ERROR");
}
} catch (InterruptedException ie) {
logger.error("Interrupted exception: " + ie.getMessage());
mainProgram.errorOnDisplay();
}
}
}
}
Sadly the first thread being stuck on listening to the comport doesn't release the claim it has on the cpu so the second thread doesn't get any CPU time. So: How to show an error on the display when the thread listening to a com port hangs?
The readResponse method that hangs, afaik it hangs on "byte firstByte = (byte) inputStream.read();" because there's nothing to read:
private void readResponse() {
byte[] bufferLeft = new byte[4];
byte[] bufferRight = new byte[2];
byte size = 0;
boolean responseFound = false;
try {
while(!responseFound) {
byte firstByte = (byte) inputStream.read();
if (firstByte == -1) {
logger.error("first byte of response is -1");
mainProgram.errorOnDisplay();
break;
}
for (int i = 0; i < 4; i++) {
bufferLeft[i] = (byte) inputStream.read();
}
size = bufferLeft[0];
if (size > 0) {
bufferRight = new byte[size];
int i2 = 0;
while (i2 < size) {
bufferRight[i2] = (byte) inputStream.read();
i2++;
}
}
if (firstByte == 1 && bufferLeft[1] == 40) {
responseFound = true;
}
}
if (size == 11) {
// some code
}
} catch(IOException ioe) {
logger.error("IO Exception in readResponse: " + ioe.getMessage());
mainProgram.errorOnDisplay();
}
}
Edit (added complete code for second thread & readResponse method)
Inputstream is initialized as follows:
serialPort = (SerialPort) commPort;
serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
inputStream = serialPort.getInputStream();
Did you tried to cheack data availability before read?
Something like:
if (inputStream.available() > 0) {
// do your read
} else {
// wait for some time and retry or trow an error
}

Termination Condition for threads in Java

I have written a multi-threaded Java application which reads a bunch of .jar files from a directory. This application spawns multiple threads and each threads reads bunch of jar files. I'm having trouble identifying the stopping condition for this application. How can i identify that all the files have been read?
The following is a snippet function which gets called from the run() method for each thread.
import java.io.*;
import java.util.Enumeration;
import java.util.jar.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipException;
import java.io.FilenameFilter;
public class ArchiveFileTest implements Runnable {
private static boolean stopAll = false;
private static int threadNumber = 0;
private int myNumber = 0;
public ArchiveFileTest () {
myNumber = threadNumber;
threadNumber++;
}
public static boolean setStopAll () {
return setStopAll(true);
}
public static boolean setStopAll (boolean b) {
stopAll = b;
return stopAll;
}
public static String[] listFiles (File parentDir,final String ext1,final String ext2,final String ext3,final String ext4) {
String allFiles[] = parentDir.list(new FilenameFilter() {
public boolean accept(File pDir, String fName) {
if (fName.endsWith("."+ext1) || fName.endsWith("."+ext2) || fName.endsWith("."+ext3) || fName.endsWith("."+ext4)) return true;
else return false;
}
});
for (int i=0; i<allFiles.length; i++)
allFiles[i] = parentDir.getAbsolutePath() + File.separator + allFiles[i];
return allFiles;
}
public ZipFile getMyZipFile (File parentDir) {
String fn[] = listFiles(parentDir, "jar", "zip", "war", "rar");
int fileNum = myNumber % fn.length;
ZipFile zFile = null;
for (int i=0; i<fn.length; i++) {
String jFile = fn[(fileNum + i)%fn.length];
try {
zFile = new ZipFile(jFile);
break;
} catch (IOException e) {
setStopAll();
}
}
return zFile;
}
public void doStuff() throws Exception {
File dName = new File("/home/sqatest/chander/sample-files");
final int N_TIMES = 15;
final int N_FILES = 500;
int counter = 0;
int fCount = 0;
if (!dName.isDirectory() || !dName.exists()) {
System.err.println("The parent directory given should point to an existing directory...");
setStopAll();
return;
}
while (counter < N_TIMES) {
ZipFile zipFile = getMyZipFile(dName);
if (zipFile == null) {
System.err.println("No zip file entry for the Thread-" + myNumber);
break;
}
try {
Enumeration <? extends ZipEntry> zipEntries = zipFile.entries();
fCount = 0;
ZipEntry ze = null;
while (zipEntries.hasMoreElements()) {
ze = zipEntries.nextElement();
if (ze.isDirectory()) continue; // if it is a directory go to next entry
InputStream is = zipFile.getInputStream(ze);
fCount++;
int readCount = 0;
try {
while(is.read((new byte[50])) != -1 && readCount != 200) readCount++;
System.out.println("Successfully Read " + zipFile.toString());
//is.close();
} catch (IOException e) {
e.printStackTrace();
}
if (fCount == N_FILES) break; // read maximum of N_FILES
}
if (stopAll) break;
} catch (Exception e) {
e.printStackTrace();
} finally {
counter++;
}
}
}
public void run () {
try {
doStuff();
} catch (IOException e) {
e.printStackTrace();
setStopAll();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main (String[] args) throws Exception {
final int MAX_THREADS = 500;
final int MAX_HOLDING_THREADS = 5;
int loopCount = 0;
Thread mainThread = Thread.currentThread();
for (int m=0; ; m++) {
Thread t[] = new Thread[MAX_HOLDING_THREADS];
for (int n=0; n<t.length; n++) {
t[n] = new Thread(new ArchiveFileTest());
t[n].start();
if ((m+1)*(n+1)==MAX_THREADS) {
System.out.println("\n" + MAX_THREADS + " reached... \nMain Sleeping for some mins...");
loopCount++;
try {
t[n].join();
System.out.println("\nMain is back... (" + loopCount + ")");
} catch (InterruptedException e) {
e.printStackTrace();
setStopAll();
}
m = 0;
}
}
}
}
}
I don't think your application will ever stop. You've got an infinite loop in the main method:
for (int m=0; ; m++) {
....
}
Note, setting m=0 inside the body won't break the loop, so I think you'll never end even if you have no file. It then continuously reads all zip/jar/war/rar files in the directory (choosing the file based on a rotating counter myNumber is not very maintainable), but never exits the loop.
If you're requirement is to read ZIP files using a number of threads, then I would go about it a different way.
Create a Set of files which you want to look at.
Create a ThreadPoolExecutor to create a fixed pool of 5 threads
Iterate over the set of files and create a new Runnable which does the Zip Extraction (though I'm not quite sure why you read the first 10000 bytes of a ZIP entry and then don't do anything with it), and call the execute method. That will use the thread pool to process 5 files at a time.
After submitting all the runnables Use the shutdown method, which will wait for all submitted tasks to finish, and the shutdown the thread pool.
If by stopping you mean terminating then the application will stop when all threads, that are not daemon special case, are finished.
In your class that launches the threads, have a volatile counter for your running threads.
In your thread constructor pass a reference to the launching class.
Have a synchronized method to let the threads notify the launching class that they are done.
After instancing and starting your threads wait for the counter to become 0;
while(getRunningThreads() > 0) // getRunningThreads must be synchronized too
Thread.sleep(500); // Check every half second.

Categories

Resources