How to write a sound (WAV) out to a file - java

So, I am to write a copy of the sound that I manipulated into a playable format, but whenever I try it, the files are very small (< 1kb), and they don't play, most likely because it is not readable data. Here is the code
public void play(int pause, String filename, String path) throws InterruptedException {
for (int i =0; i < numWords; i++) {
myWordArray[i].blockingPlay();
Thread.sleep(pause); // 300 m.seconds, as listed in main method parameter
File file = new File(path, filename);
try{
PrintWriter output = new PrintWriter(file);
output.println(myWordArray[i]);
output.close();
} catch(IOException ex) {
System.out.printf("ERROR: %s\n", ex);
}
}
}
I'm guessing PrintWriter only works for strings, which is why my WAV file is getting corrupted when I try to play? What should I substitute for this?
EDIT-
So, using the guides posted in the comments, I modified the code, however, now it does not create a file at all. Here is the code in my audio class...
public void play(int pause, String filename, String path) throws InterruptedException {
for (int i =0; i < numWords; i++) {
myWordArray[i].blockingPlay();
Thread.sleep(pause); // 300 m.seconds, as listed in main method parameter
File file = new File("C:\\Users\\Justin\\Desktop\\JavaMedia\\", "thisisatest.wav");
try{
InputStream fis = new FileInputStream(file);
byte[] buffer = new byte[(int)file.length()];
fis.read(buffer, 0, buffer.length);
fis.close();
}
catch(IOException ex){
System.out.printf("ERROR: %s\n", ex);
}
}
}
Here is the call in my main...
myPoem.play(300,"thisisatest_pause.wav", "C:\\Users\\Justin\\Desktop\\JavaMedia\\");
I want the "thisisatest_pause.wav" to be the new file it creates, but it doesn't create one at all.

Because myWordArray[i] is an Object. So it will write myWordArray[i].toString() to the file, not the sound.
Are you using Sound#blockingPlay() from http://coweb.cc.gatech.edu/mediaComp-plan/uploads/101/bookClasses-3-9-10.zip. If yes, it has writeToFile() method to write a sound to file.

Related

Reading a binary file into byte array

I need to read a binary file and save each byte into a byte array. I've read other stackoverflow posts on this topic, but cannot figure out why mine does not work. Here is what I have:
String fileOne = "file1.bin";
byte[] byteArray = new byte[1000];
try{
FileInputStream fileIS = new FileInputStream(fileOne);
ObjectInputStream is = new ObjectInputStream(fileIS);
is.read(byteArray);
is.close();
for(int i =0; i < byteArray.length; i++){
System.out.println(byteArray[i]);
}
}
catch (FileNotFoundException e){
e.toString();
System.exit(0);
}
catch (IOException io){
io.toString();
System.exit(0);
}
Here's a way to read the contents of a file into a byte array. FileInputStream is all you need – leave ObjectInputStream out of it (unless you are explicitly dealing with data that was created from an ObjectOutputStream, but that doesn't seem to be the case since you are calling println() on each byte).
public static void main(String[] args) {
String filename = "file1.bin";
try (FileInputStream fis = new FileInputStream(filename)) {
byte[] bytes = fis.readAllBytes();
for (byte b : bytes) {
System.out.print(b);
}
} catch (Exception e) {
e.printStackTrace();
}
}
A few things here:
omit using ObjectInputStream – not needed for reading byte data, and won't work unless the data was created by the corresponding output stream. From the Javadoc: "An ObjectInputStream deserializes primitive data and objects previously written using an ObjectOutputStream. "
use try with resources – it will close the associated stream for you
catch Exception – in the code you posted, you will only see info if FileNotFoundException or IOException is thrown. For anything else, your code doesn't handle them or print out any info.

How to write a list of files in Java

I have a class in Java which write a file using FileOutputStream and BufferedOutputStream. This is working fine but my intention is that I want to write any number of files in java not just one. Here is my code written in Java
public class FileToBeTaken{
public void fileBack(byte [] output) {
FileOutputStream fop = null;
BufferedOutputStream bos = null;
File file;
try {
file= new File("/Users/user/Desktop/newfile.txt");
fop = new FileOutputStream(file);
bos = new BufferedOutputStream(fop);
// if file doesnt exists, then create it
if (!file.exists()) {
file.createNewFile();
}
bos.write(output);
bos.flush();
bos.close();
System.out.println("Done");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bos != null) {
bos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Here fileBack method is called from another class inside a for loop n times. so for each time I need to write a new file onto my desktop as my code is I just take only the file for the last iteration. Also I should mention that for each iteration as parameter to this class is send one array of bytes which is taken by "byte [] output
Change
public void fileBack(byte [] output) {
to
public void fileBack(String fileName, byte [] output) {
Then change where you call method fileBack in your other class by providing the file name there. ie
byte output[] = //You already provide this byte array
String fileName = "/Users/user/Desktop/newfile.txt"
fileBack(fileName, output);
Try taking in the file path ..newfile.txt and making it into a parameter for the function. Then you can put a for loop in main or whoever is instantiating this object and call it n times. Does that help at all?
just add one static and private integer field inside FileToBeTaken class.
private static int index=0;
so there is no need to pass name of file to this class as you mentioned in question comments.
because i want to create these file names inside this class i wrote above
then use it in fileBack method and each time incremet it once in that method.
here is the changes on your code:
public class FileToBeTaken {
// index or number of new file, also number of all written files
// because it increments each time you call fileBack method.
private static int index = 0;
public void fileBack(byte[] output) {
FileOutputStream fop = null;
BufferedOutputStream bos = null;
File file;
try {
// use user_dir to place files on desktop,
// even on other machines which have other names except user.
String user_dir = System.getProperty("user.home").replace("\\", "/");
// use index to create name of file.
file = new File(user_dir+"/Desktop/newfile_" + (index++) + ".txt");
fop = new FileOutputStream(file);
bos = new BufferedOutputStream(fop);
// if file doesnt exists, then create it
if (!file.exists()) {
file.createNewFile();
}
bos.write(output);
bos.flush();
bos.close();
System.out.println("Done - "+file.getName());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bos != null) {
bos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
how to use it:
for (int i = 0; i < 10; i++) {
new FileToBeTaken().fileBack("some text".getBytes());
}
the output:
Done - newfile_0.txt
Done - newfile_1.txt
Done - newfile_2.txt
Done - newfile_3.txt
Done - newfile_4.txt
Done - newfile_5.txt
Done - newfile_6.txt
Done - newfile_7.txt
Done - newfile_8.txt
Done - newfile_9.txt

Text is not appended in new file in attempt to make a text file manipulator

Problem and where I'm at: I can't append text into these new files I create with the program. Currently it only copies files but does not append them. See line with comment
"// append file name into the new file ".
Secondly, the final dump file seems to only append the .java file, it's not reading or appending the input files.
The explanation of what I'm trying to do:
The long and short is that I am trying to make a program that will be placed into random folders with .txt files filled with data.
I need the program to
Look within the realm of the folder it is in only
Then take any .txt file and
a) make a copy but append the original file name into the text body (at the top), inside a sub-folder like "< filenamehere.txt" into the body (at the top)
b) then copy body contents of the original.txt
c) take the prepended .txt file and append it to a single dump.txt file
d) repeat this for all local txt files and keep appending to the end of the dump.txt file
So at the end, if I had 7 files, I will have 7 appended copies and 1 giant dump file containing everything of the 7 appended copies. So for example, if I had three text files, each one having only one word in them. So a.txt, b.txt, c.txt
and the three words are "Hello world !". The a.txt copy would have the contents inside
">a.txt
Hello
"
Right now it's just copying the Hello (original body content) but not appending the >a.txt. The final dump text file is not accumulating anything from the other files, but it's strangely enough picking up the source code from the .java file. So essentially, I get a //Output folder and inside are the copies of the .txt files and a megaDump.txt that manages to pick up the .java text, but no other text files are appended.
import java.io.* ;
import java.nio.file.*;
public class FilePrepender // class name
{
public static void main (String [] args)
{
// make a giant dump file which we will append all read files into
try {
new File("Output\\").mkdirs();
File megaDumpFile = new File("Output\\masterDump.txt");
if (megaDumpFile.createNewFile()) {
System.out.println("File creation success");
} else {
System.out.println("File was not made. File already exists. Please delete");
}
} catch (IOException e) {
}
//grab file names
File folder = new File(".");
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
listOfFiles[i].getName();
} else if (listOfFiles[i].isDirectory()) {
//do nothing
}
}
//open files + duplicate + prepend + and append product to end of master dump file
// main for
for (int j = 0; j < listOfFiles.length; j++){
//append file name for mega dump file
String fileNameTemp = listOfFiles[j].getName(); // get file name
try {
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("Output//masterDump.txt", true)));
out.println(fileNameTemp);
out.flush();
out.close();
}
catch (IOException e) {
}
// duplicate input files
FileInputStream instream = null;
FileOutputStream outstream = null;
try {
File infile =new File(""+listOfFiles[j].getName());
File outfile =new File("Output\\"+listOfFiles[j].getName());
instream = new FileInputStream(infile);
outstream = new FileOutputStream(outfile);
byte[] buffer = new byte[1024];
int length;
// apend file name into the new file
// String fileNameTemp = listOfFiles[j].getName(); // get file name
try {
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("Output//masterDump.txt", true)));
out.println(">"+fileNameTemp);
out.flush();
out.close();
}
catch (IOException e) {
}
// now copy contents of previous file into the new file
/*copying the contents from input stream to
* output stream using read and write methods
*/
while ((length = instream.read(buffer)) > 0){
outstream.write(buffer, 0, length);
}
//Closing the input/output file streams
instream.close();
outstream.close();
// file is copied
} catch(IOException ioe) {
}
// copy newly copied file into mega dump
try {
File infile =new File("Output\\"+listOfFiles[j]); // newly copied
File outfile =new File("Output\\masterDump.txt");
instream = new FileInputStream(infile);
outstream = new FileOutputStream(outfile);
byte[] buffer = new byte[1024];
int length;
/*copying the contents from input stream to
* output stream using read and write methods
*/
while ((length = instream.read(buffer)) > 0){
outstream.write(buffer, 0, length);
}
//Closing the input/output file streams
instream.close();
outstream.close();
// file is copied
} catch(IOException ioe) {
}
} // end for loop
} // end main
} // end class
There are quite a few issues here:
You use for your file paths sometimes slash, sometimes 2 backslashes and sometimes even double slashes which resulted in problems at least on my Mac. Just use regular forward slashes.
The code did not filter for .txt files yet, so everything which was in the current directory was processed - even the executing program itself.
Currently the code wrote the > sometext.txt lines directly into your masterDump.txt instead of indirectly through your file copies.
The code overwrote masterDump.txt for each iteration of the loop as the file was not opened in appending mode.
Following is the code which currently produces the following result when called in a folder with a.txt, b.txt and c.txt containing "Hello", "World" and "!" respectively. I hope this is the desired behavior.
Note that there is much to improve in this code, especially handling the errors as already pointed out in the comments.
import java.io.* ;
import java.nio.file.*;
public class FilePrepender // class name
{
public static void main (String [] args)
{
// make a giant dump file which we will append all read files into
try {
new File("Output/").mkdirs();
File megaDumpFile = new File("Output/masterDump.txt");
if (megaDumpFile.createNewFile()) {
System.out.println("File creation success");
} else {
System.out.println("File was not made. File already exists. Please delete");
}
} catch (IOException e) {
}
//grab file names
File folder = new File(".");
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
listOfFiles[i].getName();
} else if (listOfFiles[i].isDirectory()) {
//do nothing
}
}
//open files + duplicate + prepend + and append product to end of master dump file
// main for
for (int j = 0; j < listOfFiles.length; j++){
//append file name for mega dump file
String fileNameTemp = listOfFiles[j].getName(); // get file name
if (!fileNameTemp.toLowerCase().endsWith(".txt")) {
continue;
}
// duplicate input files
FileInputStream instream = null;
FileOutputStream outstream = null;
try {
File infile =new File(""+listOfFiles[j].getName());
File outfile =new File("Output/"+listOfFiles[j].getName());
instream = new FileInputStream(infile);
byte[] buffer = new byte[1024];
int length;
// apend file name into the new file
// String fileNameTemp = listOfFiles[j].getName(); // get file name
outstream = new FileOutputStream(outfile);
PrintWriter out = new PrintWriter(outstream);
out.println(">"+fileNameTemp);
out.flush();
out.close();
// now copy contents of previous file into the new file
/*copying the contents from input stream to
* output stream using read and write methods
*/
outstream = new FileOutputStream(outfile, true);
while ((length = instream.read(buffer)) > 0){
outstream.write(buffer, 0, length);
}
//Closing the input/output file streams
instream.close();
outstream.close();
// file is copied
} catch(IOException ioe) {
}
// copy newly copied file into mega dump
try {
File infile =new File("Output/"+listOfFiles[j]); // newly copied
File outfile =new File("Output/masterDump.txt");
instream = new FileInputStream(infile);
outstream = new FileOutputStream(outfile, true);
byte[] buffer = new byte[1024];
int length;
/*copying the contents from input stream to
* output stream using read and write methods
*/
while ((length = instream.read(buffer)) > 0){
outstream.write(buffer, 0, length);
}
//Closing the input/output file streams
instream.close();
outstream.close();
// file is copied
} catch(IOException ioe) {
}
} // end for loop
} // end main
} // end class
Agreeing with others: You delete your progress every time you 'touch' your masterDump file.
Here is my version:
import java.io.* ;
import java.nio.file.*;
public class FilePrepender // class name
{
public static void main (String [] args)
{
//Generates the string for the output for the right PC.
String OUTFILE="Output"+File.separator+"masterDump.txt";
// make a giant dump file which we will append all read files into
try {
new File("Output").mkdirs();
File megaDumpFile = new File(OUTFILE);
megaDumpFile.createNewFile();
} catch (IOException e) {
System.out.println("Something weird occured!");
}
File folder = new File(".");
// FileFilter filter = new istext();
// File[] listOfFiles = folder.listFiles( filter );
//grab file names
File[] listOfFiles = folder.listFiles();
try {
FileOutputStream fout = new FileOutputStream ( new File(OUTFILE));
PrintWriter pout = new PrintWriter( fout );
for (int j = 0; j < listOfFiles.length; j++){
//Hacky fix cause java is hard:
if ( ! listOfFiles[j].getName().endsWith(".txt")) { continue ; }
//append file name for mega dump file
pout.println(listOfFiles[j].getName()); // Append File-name
pout.flush(); //Probably a better way than this, but eh.
//Copy the file's text
Files.copy(listOfFiles[j].toPath(), fout);
fout.flush(); //Again, eh.
}
pout.close();
pout.close();
}
catch (IOException e) {
}
}
}
/* Ugh, IDK how to java. (This is the non-hacky way, but idk how to.)
public class istext implements FileFilter {
public static void accept(File pathname){
return( pathname.getName().endsWith(".txt"));
}
}
*/

Creating a zip file containing Text Files

I've been trying to tackle this problem for a day or two and can't seem to figure out precisely how to add text files to a zip file, I was able to figure out how to add these text files to a 7zip file which was insanely easy, but a zip file seems to me much more complicated for some reason. I want to return a zip file for user reasons btw.
Here's what I have now:
(I know the code isn't too clean at the moment, I plan to tackle that after getting the bare functionality down).
private ZipOutputStream addThreadDumpsToZipFile(File file, List<Datapoint<ThreadDump>> allThreadDumps, List<Datapoint<String>> allThreadDumpTextFiles) {
ZipOutputStream threadDumpsZipFile = null;
try {
//creat new zip file which accepts input stream
//TODO missing step: create text files containing each thread dump then add to zip
threadDumpsZipFile = new ZipFile(new FileOutputStream(file));
FileInputStream fileInputStream = null;
try {
//add data to each thread dump entry
for(int i=0; i<allThreadDumpTextFiles.size();i++) {
//create file for each thread dump
File threadDumpFile = new File("thread_dump_"+i+".txt");
FileUtils.writeStringToFile(threadDumpFile,allThreadDumpTextFiles.get(i).toString());
//add entry/file to zip file (creates block to add input to)
ZipEntry threadDumpEntry = new ZipEntry("thread_dump_"+i); //might need to add extension here?
threadDumpsZipFile.putNextEntry(threadDumpEntry);
//add the content to this entry
fileInputStream = new FileInputStream(threadDumpFile);
byte[] byteBuffer = new byte[(int) threadDumpFile.length()]; //see if this sufficiently returns length of data
int bytesRead = -1;
while ((bytesRead = fileInputStream.read(byteBuffer)) != -1) {
threadDumpsZipFile.write(byteBuffer, 0, bytesRead);
}
}
threadDumpsZipFile.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileInputStream.close();
} catch(Exception e) {
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return threadDumpsZipFile;
}
As you can sort of guess, I have a set of Thread Dumps that I want to add to my zip file and return to the user.
Let me know if you guys need any more info!
PS: There might be some bugs in this question, I just realized with some breakpoints that the threadDumpFile.length() won't really work.
Look forward to your replies!
Thanks,
Arsa
Here's a crack at it. I think you'll want to keep the file extensions when you make your ZipEntry objects. See if you can implement the below createTextFiles() function; the rest of this works -- I stubbed that method to return a single "test.txt" file with some dummy data to verify.
void zip()
{
try {
FileOutputStream fos = new FileOutputStream("yourZipFile.zip");
ZipOutputStream zos = new ZipOutputStream(fos);
File[] textFiles = createTextFiles(); // should be an easy step
for (int i = 0; i < files.length; i++) {
addToZipFile(file[i].getName(), zos);
}
zos.close();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
void addToZipFile(String fileName, ZipOutputStream zos) throws Exception {
File file = new File(fileName);
FileInputStream fis = new FileInputStream(file);
ZipEntry zipEntry = new ZipEntry(fileName);
zos.putNextEntry(zipEntry);
byte[] bytes = new byte[1024];
int length;
while ((length = fis.read(bytes)) >= 0) {
zos.write(bytes, 0, length);
}
zos.closeEntry();
fis.close();
}

Why string didn't write into file?

Function " writeToFile() " will be rapidly called to write string to text file .
but I didn't see any text in the file .
code:
public class MyClass {
private File data_file = new File("data_from_java.txt");
public void writeToFile(String str){
try {
FileOutputStream fos= new FileOutputStream(this.data_file, true);
System.out.print(str); // there is text shown in terminal
fos.write(str.getBytes());
fos.flush();
fos.close(); // why file donesn't have text
}catch(Exception ex) {
System.out.println(ex.getMessage());
}
}
Writing raw bytes may cause problems with character encoding. As Jon Skeet said, use a writer...
try {
FileWriter writer = new FileWriter(data_file, true);
writer.write(str);
} catch(IOException e) {
// oh no!
} finally {
writer.close();
}
Try using this chunk of code:
final BufferedWriter fos = new BufferedWriter(new FileWriter(data_file, true));
System.out.print(str);
fos.write(str);
fos.flush();
fos.close();
It worked for me although i did find my text file in a different place than i expected. Maybe a little searching would do already?
IN ur code fos.write(str.getBytes()); this line causes the problem it seems... write() method takes a byte as an argument.. u r giving array of bytes.. So change that line into
buf = str.getBytes();
for (int i=0; i < buf.length; i += 2) {
f0.write(buf[i]);
}

Categories