Writing byteArrays into a file issue - java

So I have a couple of methods and when I test them using an assertion test it fails, and I can't for the life of me figure out why, so if anyone can help me out, I'd greatly appreciate it.
The methods are supposed to write a block into an existing file, then read said block and make sure that the assertion works.
The Write Method:
public void writeBlock(int blockNum, AbstractDBFile f, AbstractBlock b)
throws IOException {
DBFile dbf = (DBFile) f;
Block blk = (Block) b;
if (blockNum >= dbf.totalNumOfBlocks){
dbf.totalNumOfBlocks++;
}
int header = 4096;
RandomAccessFile file = new RandomAccessFile(dbf.fileName, "rw");
file.seek(header + (blockNum) * 4096);
file.write(blk.getData(), 0, 4096);
file.close();
f.curBlockPos = blockNum + 1;
}
The Read Method:
public AbstractBlock readBlock(int blockNum, AbstractDBFile f)
throws IOException {
f.setCurBlockPos(blockNum);
DBFile f2 = new DBFile();
f2.setCurBlockPos(f.getCurBlockPos());
f2.setFileName(f.getFileName());
Block block = new Block();
int currentByte = f2.getCurBlockPos() * 4096;
byte[] data = new byte[4096];
String filename = f2.getFileName();
File ourFile = new File(filename);
RandomAccessFile file = new RandomAccessFile(ourFile, "r");
FileChannel inChannel = file.getChannel();
ByteBuffer bb = ByteBuffer.allocate(currentByte);
inChannel.read(bb);
while(inChannel.read(bb)>0){
bb.flip();
for (int i =0; i<bb.limit(); i++){
data[i]=bb.get();
block.setData(data);
}
bb.clear();
}
inChannel.close();
file.close();
return block;
}
The Block Class:
public class Block extends AbstractBlock {
#Override
public byte[] getData() {
// TODO Auto-generated method stub
/*byte[] data = new byte [4096];
data[0] = 10;
data[5] = 20;*/
return data;
}
#Override
public void setData(byte[] d) throws IOException {
int freeByte = -1;
for(int i = 0; i < data.length && freeByte < 0; i++)
if(data[i] == 0)
freeByte = i;
for(int i = freeByte, j = 0; j < d.length; i++, j++)
data[i] = d[j];
}
}
The Assertion test:
public void testWriteRead() throws IOException {
StorageManager manager = new StorageManager();
DBFile file = (DBFile)manager.createFile("File1");
byte [] write = new byte[4096];
write[0] = 10;
write[5] = 20;
Block block = new Block();
block.setData(write);
manager.writeBlock(0, file, block);
Block b = (Block) manager.readBlock(0, file);
assertTrue(areEqual(write,b.getData()));
}
private boolean areEqual(byte [] array1, byte [] array2) {
if(array1.length != array2.length)
return false;
for(int i = 0 ; i < array1.length ; i++)
if(array1[i] != array2[i])
return false;
return true;
}
I wont be doing this if I was not desperate, any help would be greatly appreciated.

Related

How to create an audio wave in JavaFX?

I would like to get an Audio wave plot using Chart Area in JavaFX. Unfortunately, I am not clear how to do, what are the values ​​to be extracted from the sound to assign to x-axis and y-axis?
I tried to read other posts, but I found nothing on javafx.
You can help me?
Sample Image:
Below is the code that extract the waveform .
I'm pulling out the right parameters for my scope?
How can I use it to print the graph with JavaFX?
public class SimpleWaveformExtractor implements WaveformExtractor {
private static final int DEFAULT_BUFFER_SIZE = 32768;
#Override
public double[] extract(File inputFile) {
AudioInputStream in = null;
try {
in = AudioSystem.getAudioInputStream(inputFile);
} catch (Exception e) {
System.out.println("Cannot read audio file");
return new double[0];
}
AudioFormat format = in.getFormat();
byte[] audioBytes = readBytes(in);
int[] result = null;
if (format.getSampleSizeInBits() == 16) {
int samplesLength = audioBytes.length / 2;
result = new int[samplesLength];
if (format.isBigEndian()) {
for (int i = 0; i < samplesLength; ++i) {
byte MSB = audioBytes[i * 2];
byte LSB = audioBytes[i * 2 + 1];
result[i] = MSB << 8 | (255 & LSB);
}
} else {
for (int i = 0; i < samplesLength; i += 2) {
byte LSB = audioBytes[i * 2];
byte MSB = audioBytes[i * 2 + 1];
result[i / 2] = MSB << 8 | (255 & LSB);
}
}
} else {
int samplesLength = audioBytes.length;
result = new int[samplesLength];
if (format.getEncoding().toString().startsWith("PCM_SIGN")) {
for (int i = 0; i < samplesLength; ++i) {
result[i] = audioBytes[i];
}
} else {
for (int i = 0; i < samplesLength; ++i) {
result[i] = audioBytes[i] - 128;
}
}
}
return ArraysHelper.normalize(result);
}
private byte[] readBytes(AudioInputStream in) {
byte[] result = new byte[0];
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
try {
int bytesRead = 0;
do {
bytesRead = in.read(buffer);
result = ArrayUtils.addAll(result, buffer);
} while (bytesRead != -1);
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
}
this is the interface:
public interface WaveformExtractor {
double[] extract(File in);
}
This is the code that return the array of double:
private double[] extractWaveform(File file) throws IOException, UnsupportedAudioFileException {
return new WavFileExtractor().extract(file);
}

Compare two files by byte blocks java

I try to compare two files by byte blocks. Block by block. But I have a problem with my loop-tree.
public void compare() {
File file1 = arrayOfFiles.get(i);
File file2 = arrayOfFiles.get(y);
if (file1.length() != file2.length()) {
break;
}
else
{
for (int z = 0; ; z++) {
byte[] b1 = getParts(file1, z);
byte[] b2 = getParts(file2, z);
if (b1.length != b2.length) {
break;
}
else
{
for (int x = 0; ; x++) {
if (b1[x] != b2[x]) {
break;
}
else
{
//how can I find the end of file? and compare last [x] of b1 and b2?
}
}
}
}
}
}
private static byte[] getParts(File file, int z) throws IOException {
byte [] bytes = new byte[1024];
int point = z * 1024;
RandomAccessFile raf = new RandomAccessFile(file, "r");
FileChannel fc = raf.getChannel();
MappedByteBuffer buffer = fc.map(FileChannel.MapMode.READ_ONLY, point, 1024);
buffer.get(bytes);
buffer.clear();
return bytes;
}
Is there another way to compare two files by bytes and do it with block of different size?
To compare last byte block of files your program could benefit from minor modification. Start iterating blocks from the last block. Changed the for clauses as following to iterate backwards.
import java.lang.Math;
import java.nio.channels.FileChannel;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
public class Compare
{
public static final int BLOCK_SIZE = 1024;
public boolean compare(File file1, File file2)
{
//File file1 = arrayOfFiles.get(i);
//File file2 = arrayOfFiles.get(y);
boolean equal = file1.length() != file2.length();
for (int z = getSizeInBlocks(file1) - 1; equal && 0 <= z ; z--)
{
MappedByteBuffer b1 = getParts(file1, z);
MappedByteBuffer b2 = getParts(file2, z);
if (b1.remaining() != b2.remaining())
{
equal = false;
break;
}
else
{
for (int x = getBlockSize() - 1; equal && 0 <= x; x--)
{
if (b1[x] != b2[x])
{
equal = false;
break;
}
else
{
//how can I find the end of file? and compare last [x] of b1 and b2?
}
}
}
}
return equal;
}
private static int getSizeInBlocks(File file)
{
return (int) Math.ceil((double)getBlockSize()/file.length());
}
private static int getBlockSize()
{
return BLOCK_SIZE;
}
private static ByteBuffer getParts(File file, int z)
throws IOException
{
int point = z * getBlockSize();
RandomAccessFile raf = new RandomAccessFile(file, "r");
FileChannel fc = raf.getChannel();
MappedByteBuffer buffer = fc.map(
FileChannel.MapMode.READ_ONLY,
point,
getBlockSize());
return buffer;
}
}

Java - Writing a Method to Count Lines In a Text File Without Throwing Exceptions

Below is a solution from Number of lines in a file in Java
to quickly count the number of lines in a text file.
However, I am trying to write a method that will perform the same task without throwing an 'IOException'.
Under the original solution is my attempt to do this with a nested try-catch block <-- (Is this usually done/frowned upon/ or easily avoidable??) which returns 0 no matter how many lines are in the given file (obviously a fail).
Just to be clear, I am not looking for advice on how to better use the original method that does contain the exception and, therefore, the context within which I am using it is irrelevant to this question.
Can somebody please help me write a method that counts the number of lines in a text file and does not throw any exceptions? (In other words, deals with potential errors with a try-catch.)
Original line counter by martinus:
public static int countLines(String filename) throws IOException {
InputStream is = new BufferedInputStream(new FileInputStream(filename));
try {
byte[] c = new byte[1024];
int count = 0;
int readChars = 0;
boolean empty = true;
while ((readChars = is.read(c)) != -1) {
empty = false;
for (int i = 0; i < readChars; ++i) {
if (c[i] == '\n') {
++count;
}
}
}
return (count == 0 && !empty) ? 1 : count;
} finally {
is.close();
}
}
My Attempt:
public int countLines(String fileName ) {
InputStream input = null;
try{
try{
input = new BufferedInputStream(new FileInputStream(fileName));
byte[] count = new byte[1024];
int lines = 0;
int forChar;
boolean empty = true;
while((forChar = input.read(count)) != -1){
empty = false;
for(int x = 0; x < forChar; x++){
if(count[x] == '\n'){
lines++;
}
}
}
return (!empty && lines == 0) ? 1 : lines + 1;
}
finally{
if(input != null)
input.close();
}
}
catch(IOException f){
int lines = 0;
return lines;
}
}
It is more robust to use char instead of byte for '\n' and return -1 in case of any errors, for example if the filename does not exist:
public static int countLines(String filename) {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(filename)));
char[] c = new char[1024];
int count = 0;
int readChars = 0;
boolean emptyLine = true;
while ((readChars = br.read(c)) != -1) {
for (int i = 0; i < readChars; ++i) {
emptyLine = false;
if (c[i] == '\n') {
++count;
emptyLine = true;
}
}
}
return count + (!emptyLine ? 1 : 0);
} catch (IOException ex) {
return -1;
} finally {
if (br != null)
try {
br.close();
} catch (IOException e) {
// Ignore intentionally
}
}
}
Sharing my attempt.
public static int countLines(String filename) {
InputStream is = new BufferedInputStream(new FileInputStream(filename));
int numLines = 0;
try {
byte[] c = new byte[1024];
int count = 0;
int readChars = 0;
boolean empty = true;
while ((readChars = is.read(c)) != -1) {
empty = false;
for (int i = 0; i < readChars; ++i) {
if (c[i] == '\n') {
++count;
}
}
}
numLines = (count == 0 && !empty) ? 1 : count;
} catch (IOException ex) {
numLines = 0;
} catch (FileNotFoundException ex) {
System.out.println("File not found.");
numLines = 0;
} finally {
is.close();
}
return numLines;
}

Java output values over time

I have an audio file that I am converting into a byte array, but then you cannot tell when that byte value is actually played in the song. So I am trying to stretch it out over the length of the song.
So while the song is playing, it outputs the byte value. How is this possible?
Here is my code so far:
public class Main {
private static final String FILENAME = "assets/pf.wav";
private static double[] endResult = null;
public static void convert() throws IOException{
ByteArrayOutputStream out = new ByteArrayOutputStream();
BufferedInputStream in = new BufferedInputStream(new FileInputStream(FILENAME));
int read;
byte[] buff = new byte[1024];
while ((read = in.read(buff)) > 0)
{
out.write(buff, 0, read);
}
out.flush();
byte[] audioBytes = out.toByteArray();
endResult = calculateFFT(audioBytes);
}
public static double[] calculateFFT(byte[] signal)
{
final int mNumberOfFFTPoints =1024;
double mMaxFFTSample;
double temp;
Complex[] y;
Complex[] complexSignal = new Complex[mNumberOfFFTPoints];
double[] absSignal = new double[mNumberOfFFTPoints/2];
for(int i = 0; i < mNumberOfFFTPoints; i++){
temp = (double)((signal[2*i] & 0xFF) | (signal[2*i+1] << 8)) / 32768.0F;
complexSignal[i] = new Complex(temp,0.0);
}
y = FFT.fft(complexSignal);
mMaxFFTSample = 0.0;
int mPeakPos = 0;
for(int i = 0; i < (mNumberOfFFTPoints/2); i++)
{
absSignal[i] = Math.sqrt(Math.pow(y[i].re(), 2) + Math.pow(y[i].im(), 2));
if(absSignal[i] > mMaxFFTSample)
{
mMaxFFTSample = absSignal[i];
mPeakPos = i;
}
}
return absSignal;
}
public static void main(String[] args) throws UnsupportedAudioFileException, IOException {
File file = new File(FILENAME);
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(file);
AudioFormat format = audioInputStream.getFormat();
long frames = audioInputStream.getFrameLength();
final double durationInSeconds = (frames+0.0) / format.getFrameRate();
try {
convert();
for(int i = 0; i < endResult.length; i++) {
System.out.println(endResult[i]);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
How can I print out the value of the byte array (endResult[i]) over time and not immediately?
Whenever you print out a value, do:
Thread.sleep(100);
To wait 100 milliseconds (0.1 seconds) before printing the next value. This is adjustable of course.

I can't manage to copy files from assets to external storage

I am making an Android application, and I would like to add two files named fsx.xml and xplane.xml. This is the code I am using, it runs perfectly without errors, but the /planesim just appears empty. Please help!
String planesimFolderName = "/planesim";
String fsxFile = "fsx.xml";
String xplaneFile = "xplane.xml";
String asset;
File assetDestination;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
final File planesimFolder = new File(Environment.getExternalStorageDirectory() + planesimFolderName);
final AssetManager assetManager = getAssets();
for (int fileCount = 1; fileCount == 2; fileCount++) {
if (fileCount == 1) {
asset = fsxFile;
} else if (fileCount == 2) {
asset = xplaneFile;
}
assetDestination = new File(Environment.getExternalStorageDirectory() + planesimFolderName + "/" + asset);
try {
InputStream in = assetManager.open(asset);
FileOutputStream f = new FileOutputStream(assetDestination);
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = in.read(buffer)) > 0) {
f.write(buffer, 0, len1);
}
f.close();
} catch (Exception e) {
Log.d("CopyFileFromAssetsToSD", e.getMessage());
}
}
}
Thanks for your time and help, zeokila.
This is your mistake:
for (int fileCount = 1; fileCount == 2; fileCount++)
which is like:
int fileCount = 1;
while(fileCount == 2) // never true...
The for loop never executed (because 1 != 2), should be:
for (int fileCount = 1; fileCount <= 2; fileCount++)

Categories

Resources