Path to read a sound out of my package - java

I have a Sons class which load and play sounds. And an adhd class which contain the main and uses this Sons class.
All my classes are in the package "adhd" and my sounds in the jar, are like this : 1.wav is in SoundN which is in the jar. (ADHD.jar/SoundN/1.wav).
When I run the code in Eclipse it works, but when I run the jar it doesn't. It is important for me to keep the sounds "loading" because I need my program to read my sounds quickly, as I am using timers. What do you suggest me to do?
Here is the code of my class Sons which load sounds in instances of singletons.
Sons
package adhd;
import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;
import java.applet.Applet;
import java.applet.AudioClip;
import java.net.URL;
public class Sons {
private static String PATH=null;
private static Sons instance;
private final Map<String, Clip> sons;
private boolean desactive;
Sons(String path) {
PATH = path;
sons = new HashMap<String, Clip>();
}
public void load(String nom) throws UnsupportedAudioFileException, IOException, LineUnavailableException {
Clip clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(getClass().getResourceAsStream(PATH + nom)));
sons.put(nom, clip);
}
public void play(String son) {
if(!desactive) try {
Clip c = getSon(son);
c.setFramePosition(0);
c.start();
} catch(Exception e) {
System.err.println("Impossible to play the sound " + sound);
desactive = true;
}
}
}
Here is the adhd class which contain the main that uses sounds
Main class : adhd
public static void main(String[] args) {
Sons sonN= new Sons("/SoundN/");
try {
sonN.load("1.wav");
} catch (UnsupportedAudioFileException | IOException
| LineUnavailableException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
sonN.play("1.wav");
}
Here is also a picture of the tree

Now, thanks to the exception message, we know what the problem actually is. The problem is not that the sounds can't be loaded or aren't found in the jar. The problem is that, as the javadoc says:
These parsers must be able to mark the stream, read enough data to determine whether they support the stream, and, if not, reset the stream's read pointer to its original position. If the input stream does not support these operation, this method may fail with an IOException.
And the stream returned by Class.getResourceAsStream(), when the resource is loaded from a jar, doesn't support these operations. So what you could do is to read everything from the input stream into a byte array in memory, create a ByteArrayInputStream from this byte array, and pass that stream to AudioSystem.getAudioInputStream().
If loading everything in memory is not an option because the sound is really long (but then I guess you wouldn't put it in the jar), then you could write it to a temporary file, and then pass a FileInputStream to AudioSystem.getAudioInputStream().

Related

Cannot read the array length because "<local1>" is null

I am making a stock market simulator app in java, and there is an issue in the deleteHistoryFiles() method. It says that array is null. However, I have no idea what array this error is talking about.
Here's the code (I've deleted some methods to save space):
package stock.market.simulator;
import java.util.Random;
import java.text.DecimalFormat;
import java.util.Timer;
import java.util.TimerTask;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class StockMarketSimulator {
// Path to where the files are stored for rate history
// USE WHEN RUNNING PROJECT IN NETBEANS
//public static final String HISTORYFILEPATH = "src/stock/market/simulator/history/";
// Path to history files to be used when executing program through jar file
public static final String HISTORYFILEPATH = "history/";
public static void main(String[] args) throws IOException {
accountProfile accProfile = accountCreation();
stockProfile[][] stockProfile = createAllStocks();
deleteHistoryFiles(new File(HISTORYFILEPATH));
createHistoryFiles(stockProfile);
mainWindow window = new mainWindow(accProfile, stockProfile);
recalculationLoop(stockProfile, window);
}
// Procedure to create the history files
public static void createHistoryFiles(stockProfile[][] stocks) throws IOException {
String fileName;
FileWriter fileWriter;
for (stockProfile[] stockArray : stocks) {
for (stockProfile stock : stockArray) {
fileName = stock.getProfileName() + ".csv";
fileWriter = new FileWriter(HISTORYFILEPATH + fileName);
}
}
}
// Procedure to delete the history files
public static void deleteHistoryFiles(File directory) {
for (File file : directory.listFiles()) {
if (!file.isDirectory()) {
file.delete();
}
}
}
}
I got the same exception in exactly the same scenario. I tried to create an array of files by calling File.listFiles() and then iterating the array.
Got exception Cannot read the array length because "<local3>" is null.
Problem is that the path to the directory simply does not exist (my code was copied from another machine with a different folder structure).
I don't understand where is <local1> (sometimes it is <local3>) comes from and what does it mean?
It should be just like this: Cannot read the array length because the array is null.
Edit (answering comment) The sole interesting question in this question is what is a <local1>
My answer answers this question: <local1> is just an array created by File.listFiles() method. And an array is null because of the wrong path.

Apache Camel - not moving file

I cannot figure out what I am doing wrong here. I have tried all sorts of things, including absolute paths, relative, enabling logging (which also doesnt seem to be working, using Main, using DefaultCamelContext, adding threadsleep, but I cannot get camel to move a file from one folder to another.
Here is my code:
package scratchpad;
import org.apache.camel.CamelContext;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.dataformat.beanio.BeanIODataFormat;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.main.Main;
import org.apache.camel.spi.DataFormat;
public class CamelMain {
private static Main main;
public static void main(String[] args) throws Exception {
main = new Main();
main.addRouteBuilder( new RouteBuilder() {
#Override
public void configure() throws Exception {
// DataFormat format = new BeanIODataFormat(
// "org/apache/camel/dataformat/beanio/mappings.xml",
// "orderFile");
System.out.println("starting route");
// a route which uses the bean io data format to format a CSV data
// to java objects
from("file://input?noop=true&startingDirectoryMustExist=true")
.to("file://output");
}
});
//main.run();
main.start();
Thread.sleep(5000);
main.stop();
}
}
Can someone spot anything wrong with the above?
Thanks
You can for example read from the free chapter 1 for the Camel in Action book, as it has a file copied example it covers from top to bottom.
The pdf can be downloaded here: http://manning.com/ibsen/

Recursively moving files from one directory to another only partially completes

Based on an answer to: List all files from a directory recursively with Java
I have written a little Filemover which will recursively move every file from a directory and place them in the top level of another directory. But for some reason, the code doesn't move all the files. I switched to using Files.move() but while definitely worth while the code is still not walking the directory tree properly. Now I am getting a java.nio.file.NoSuchFileException while trying to move the files.
The stack trace says that its an unknown source, yet when I look to see if the file is there it is. I have isolated the problem to Files.move() but I can't seems to fix it. I have tried both getPath() and getAbsolutePath(). What's even weirder I use a similar method in my sorting routine and it works fine. The only difference is that my source directory has no subdirectories.
I have solved the partial tree walk. It was caused because my ImageFilter only had lower case extensions and the filter needed to be case sensitive. So I fixed it here.
Okay, I switched my little Filemover back to file.renameTo() and it works properly now. It's just a testing tool for randomly moving files into a drop directory for my image sorter so it's not worth figuring out why I was getting no such file exceptions. I was just modifying it to work recursively so it could be used to reverse a sort if someone used the wrong sorting routine on a bunch of images.
Thanks for all your help :)
I have 3 classes
import java.io.File;
import java.util.Collection;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.DirectoryFileFilter;
import ca.fotonow.p3software.ImageFileFilter;
public class PSFileUtils {
public static Collection<File> listfiles(String directory) {
// TODO Auto-generated method stub
File dir= new File (directory);
dir.mkdirs(); //create directory if it doesn't exist.
Collection<File> files= FileUtils.listFiles(dir,new ImageFileFilter(),DirectoryFileFilter.DIRECTORY);
return files;
}
}
Filter Class
import java.io.File;
import java.io.FileFilter;
import org.apache.commons.io.filefilter.IOFileFilter;
public class ImageFileFilter implements IOFileFilter {
private final String filetypes[]= new String[] {"jpeg", "JPEG","jpg","JPG","tif","TIF","tiff","TIFF","raw","RAW"};
#Override
public boolean accept(File file) {
for (String ext: filetypes) {
if (file.getName().toLowerCase().endsWith(ext)) return true;
}
return false;
}
#Override
public boolean accept(File arg0, String arg1) {
// TODO Auto-generated method stub
return false;
}
}
The main class
import java.io.File;
import java.util.Collection;
import java.util.Date;
import java.util.Random;
import java.nio.file.Files;
import static java.nio.file.StandardCopyOption.*;
public class FileMover {
/**
* #param args
*/
public static void main(String[] args) {
//Move random number of files from one directory args[0] to another directory args[1]
//directories can be relative
//Repeats randomly until files are gone
String dir1=args[0];
String dir2=args[1];
Collection<File> files=PSFileUtils.listfiles(dir1);
for (File file: files) {
File newfile=new File(dir2+"/"+file.getName());
try {
Files.move(file.toPath(),newfile.toPath(), REPLACE_EXISTING);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println((new Date()).getTime()+ " "+ newfile.getName());
Random generator =new Random(new Date().getTime());
try {
Thread.sleep(generator.nextInt(5000));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Any idea of what I have wrong?
Renaming the file might not move the file, according to the javadocs:
Many aspects of the behavior of this method are inherently platform-dependent: The rename operation might not be able to move a file from one filesystem to another, it might not be atomic, and it might not succeed if a file with the destination abstract pathname already exists. The return value should always be checked to make sure that the rename operation was successful.
Try java.nio.file.Files.move() instead.
Though #nitegazer is correct I should have used Files.move() instead of File.renameTo(). It turns out that that was not the reason for the partial file tree walk. The file tree walk was failing because the filter is case sensitive and I only provided lower case versions of the file extensions.
I did have a problem with a little script that I use to randomly fill the input hopper for testing the sorter but that just a test script and works fine with File.renameTo().

not able to include package created by own in java

I have written a program that checks a data set and provides a result, i.e. if a climate condition is given for 1000 days as data set to the program it will find any deviation in the program and provide as result that major deviation.
package main;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import faster94.*;
import rules_agarwal.*;
import algo_apriori.*;
import context_apriori.*;
import itemsets.*;
public class MainTestAllAssociationRules {
public static void main(String [] arg){
ContextApriori context = new ContextApriori();
try {
context.loadFile(fileToPath("ds1.txt"));
}
catch(Exception e)
{
e.printStackTrace();
}
/*catch (IOException e) {
e.printStackTrace();
}*/
context.printContext();
double minsupp = 0.5;
AlgoApriori apriori = new AlgoApriori(context);
Itemsets patterns = apriori.runAlgorithm(minsupp);
patterns.printItemsets(context.size());
double minconf = 0.60;
AlgoAgrawalFaster94 algoAgrawal = new AlgoAgrawalFaster94(minconf);
RulesAgrawal rules = algoAgrawal.runAlgorithm(patterns);
rules.printRules(context.size());
}
public static String fileToPath(String filename) throws UnsupportedEncodingException{
URL url = MainTestAllAssociationRules.class.getResource(filename);
return java.net.URLDecoder.decode(url.getPath(),"UTF-8");
}
}
The above is the main program. There are seven files and I have created by own package, but when I run this program as a whole I cannot run it. It complains that a package is missing. i have ready provided all the seven files.
Can any one be able to run those files?
Directory tree has to reflect package tree.
So if you have a class in a package named main you class file must be in a directory named main under the working directory. So if you execute from bin/ your class must be in bin/main.
Hope this helps
Edit
The directory tre has to look like this.
bin/
-----faster94/
--------------Classes or Subpackage
-----rules_agarwal/
-------------------Classes or Subpackage
-----algo_apriori/
------------------Classes or Subpackage
-----context_apriori/
---------------------Classes or Subpackage
-----itemsets/
--------------Classes or Subpackage
-----main/
----------MainTestAllAssociationRules and other classes or subpackages
To run this use java main.MainTestAllAssociationRules in the root (bin/) directory

Merge into Java code

Using a sample from xSocket which will run xSocketHandler as a new process, I want to customize and moving all of these code into other java file, can I copy public class xSocketDataHandler implements IDataHandler and paste into different filename say main.java?
import java.io.IOException;
import java.nio.BufferUnderflowException;
import java.nio.channels.ClosedChannelException;
import org.xsocket.*;
import org.xsocket.connection.*;
public class xSocketDataHandler implements IDataHandler
{
public boolean onData(INonBlockingConnection nbc) throws IOException, BufferUnderflowException, ClosedChannelException, MaxReadSizeExceededException
{
try
{
String data = nbc.readStringByDelimiter("\0");
//nbc.write("Reply" + data + "\0");
nbc.write("+A4\0");
if(data.equalsIgnoreCase("SHUTDOWN"))
xSocketServer.shutdownServer();
}
catch(Exception ex)
{
System.out.println(ex.getMessage());
}
return true;
}
}
No, you can't do that without reducing the visibility of xSocketDataHandler to default. If you don't want to do that, your file name should be xSocketDataHandler.java
You must be having class xSocketDataHandler in a file of the same name already since it is public. You could move other non public classes in this file to Main.java instead.
A public class will need to be in a file named according to the class, so in this case it would be xSocketDataHandler.java.
Convention is also to name java classes starting with an upper-case letter, so it would be public class XSocketDataHandler and file XSocketDataHandler.java. This isn't required, though.

Categories