import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;
public class Audio_to_bytes {
public static void main(String args[]) throws IOException
{
File WAV_FILE = new File("/home/cybersecurity/Desktop/scream.wav");
ByteArrayOutputStream out = new ByteArrayOutputStream();
AudioInputStream in = null;
try {
in = AudioSystem.getAudioInputStream(WAV_FILE);
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
int read,i;
byte[] buff = new byte[1024];
while ((read = in.read(buff)) > 0)
{
out.write(buff, 0, read);
}
out.flush();
byte[] audioBytes = out.toByteArray();
for(i=0;i<audioBytes.length;i++)
System.out.println(audioBytes[i]);
}
}
The above code is to convert the .wav file into a byte array.When I execute the program i get get many value as -128 or -127,I want to know that whether these values are exact values or the value becomes a boundary value if it exceeds the range of byte(-128 to 128),
if so can i convert the audio file into a integer array since it has a wider range.
The raw file is irrelevant since WAVE files are constructed using chunks. I suggest understanding those chunks first, RIFF File Format, to understand WAVE files.
Related
So I wrote this code that copies a file from a folder to another one!
it works fine with .mp3 .wav .jpeg.jpg files
but it doesn't work properly with .png files!
(the image is destroyed or half of it is missed)
Is there a way I can edit the code is it works with .png files?
if no, how can I copy them?
I also want to add another question! the current code works on my computer
because of this path D:\\move\\1\\1.mp3 exist on my computer!
if I convert my program to .exe file and give it to someone else it doesn't work because that path doesn't exist on his computer!
so instead of this line
FileInputStream up = new FileInputStream("D:\\move\\1\\images\\1.jpg");
i wanna make something like
FileInputStream up = new FileInputStream(findAppFolder+"\\images\\1.jpg");
code :
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
FileInputStream up = new FileInputStream("D:\\move\\1\\images\\1.jpg");
FileOutputStream down = new FileOutputStream("D:\\move\\2\\images\\2.jpg");
BufferedInputStream ctrl_c = new BufferedInputStream(up);
BufferedOutputStream ctrl_v = new BufferedOutputStream(down);
int b=0;
while(b!=-1){
b=ctrl_c.read();
ctrl_v.write(b);
}
ctrl_c.close();
ctrl_v.close();
}
}
Try this way:
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
Path source=Paths.get("abc.png");
Path destination=Paths.get("abcNew.png");
Files.copy(source, destination);
Or if you want to use with Java input/output try this way:
public void copy(File src, File dst) throws IOException {
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dst);
// Transfer all byte from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
I have send a image that is about 500kb but in the server ,the image that receive is more than 500kb.I wonder that is there any logical problems I had made? the speed of the network is about 100kb/s.
the client
package client;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.OutputStreamWriter;
import java.net.Socket;
public class client {
public static void main(String[] args) {
Socket s = null;
BufferedOutputStream bo = null;
BufferedInputStream bi = null;
try {
s = new Socket("127.0.0.1",12349);
bo = new BufferedOutputStream(s.getOutputStream());
bi = new BufferedInputStream(new FileInputStream("1.jpg"));
byte [] bys =new byte[1024];
while((bi.read(bys))!=-1){
bo.write(bys);
}
bo.flush();
System.out.println("already post the image");
bi.close();
} catch (IOException e) {
}finally{
try {
s.close();
} catch (IOException e) {
System.out.println("close failed");
}
}
}
}
server
package server;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class sserver {
public static void main(String[] args) {
ServerSocket ss = null;
Socket s = null;
BufferedOutputStream bo = null;
BufferedInputStream bs = null;
try {
ss = new ServerSocket(12349);
s = ss.accept();
bo = new BufferedOutputStream(new FileOutputStream("2.jpg"));
bs = new BufferedInputStream(s.getInputStream());
byte [] bys =new byte[1024];
while((bs.read(bys))!=-1){
bo.write(bys);
}
bo.flush();
System.out.println("upload success");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
ss.close();
} catch (IOException e) {
System.out.println("close failed");
}
}
}
}
The problem is that you are disregarding the number of bytes read:
while((bi.read(bys))!=-1){
bo.write(bys);
}
This means that you always write 1024 bytes to bo, even if you read fewer than 1024 bytes from bi.
You need to assign the number of bytes read to a variable, and pass that to the write call:
int bytesRead;
while((bytesRead = bi.read(bys))!=-1){
bo.write(bys, 0, bytesRead);
}
Please write exacte byte which you received like below
int len= 0 ;
while( ( len = bi.read(bys))!=-1){
bo.write(bys,0, len);
}
Same code change required in both client and server side. I tested at my end and found that both file has same size afterthis change
Your server code is always writing full length of bys array into output stream.
Proper way to do it:
byte [] bys =new byte[1024];
while(true) {
int numRead = bs.read(bys);
if (numRead == -1)
break;
bo.write(bys, 0, numRead);
}
I use io scanner / System.out to copy text files. I tried using the same technique to copy pdf, video and image files. The result was that the files were copied, but they were corrupt (cannot open them). Also, the file size does not equal the original file size.
code
import java.awt.Desktop;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.Scanner;
public class ScannerTest {
public static void main(String[] args) throws IOException {
PrintStream out =System.out;
long start = System.currentTimeMillis();
copyFile(new File("H:\\a.pdf"), new File("H:\\b.pdf"));// 2 file input, output
System.setOut(out);
System.out.println(System.currentTimeMillis()-start);
}
static String text=null;
public static void copyFile(File input,File output) throws IOException{
//Scanner read file
Scanner in= new Scanner(new FileInputStream(input));
StringBuilder builder =new StringBuilder();
try {
while(in.hasNextLine()){
text=in.nextLine();
builder.append(text);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
in.close();
}
//System.out
try {
OutputStream outputStream = new FileOutputStream(output);
PrintStream printStream = new PrintStream(outputStream);
System.setOut(printStream);
System.out.println(new String(builder));
Desktop.getDesktop().open(output);
} catch (Exception e) {
e.printStackTrace();
}
}
}
p/s: Not use IO other.(ex: BufferedInput/OutputStream)
There are two problems (at least):
you use nextLine() which will read up to the next "\r\n"', '\n', '\r', '\u2028', '\u2029' or '\u0085' and discard what ever it found as line separator (one or two characters). As you are not even using append(text).append('\n') I doubt that this will correctly copy multi-line text, let alone binary files where each of the possible line-terminators may have a different meaning.
you use Scanner and StringBuilder which are not safe for binary data. As the Documentation on new Scanner(java.io.InputStream) states:
Bytes from the stream are converted into characters using the underlying platform's default charset.
If any byte-sequence in you input file is not valid as e.g. UTF-8 (which is a common default charset) it is silently replaced by a generic 'could not read input'-character. For text-files this can mean, that a 'ä' is converted to '�', for binary files this can render the whole file unusable.
If you want to copy arbitrary (possibly binary) files I would recommend not taking any chances and stick to byte[] APIs. You could however also use a charset which is known to accept all byte-sequences unchanged like ISO-8859-1 when creating Scanner and PrintStream; you would than still need to refrain from using line-APIs that suppress the found line-separator.
This should do the trick:
import java.awt.Desktop;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
/**
* Created for http://stackoverflow.com/a/25351502/1266906
*/
public class CopyFile {
public static void main(String[] args) {
long start = System.currentTimeMillis();
copyFile(new File("H:\\a.pdf"), new File("H:\\b.pdf"));// 2 file input, output
System.out.println(System.currentTimeMillis() - start);
}
public static void copyFile(File input, File output) {
try {
try (FileInputStream inputStream = new FileInputStream(input);
OutputStream outputStream = new FileOutputStream(output)) {
byte[] buffer = new byte[4096];
do {
int readBytes = inputStream.read(buffer);
if (readBytes < 1) {
// end of file
break;
} else {
outputStream.write(buffer, 0, readBytes);
}
} while (true);
}
// Open result
Desktop.getDesktop().open(output);
} catch (Exception e) {
e.printStackTrace();
}
}
}
pre Java 7 you need to use try-finally:
public static void copyFile(File input, File output) {
try {
FileInputStream inputStream = new FileInputStream(input);
try {
OutputStream outputStream = new FileOutputStream(output);
try {
byte[] buffer = new byte[4096];
do {
int readBytes = inputStream.read(buffer);
if (readBytes < 1) {
// end of file
break;
} else {
outputStream.write(buffer, 0, readBytes);
}
} while (true);
} finally {
outputStream.close();
}
} finally {
inputStream.close();
}
// Open result
Desktop.getDesktop().open(output);
} catch (Exception e) {
e.printStackTrace();
}
}
I am reading a video file data in bytes and sending to another file but the received video file is not playing properly and is chattered.
Can anyone explain me why this is happening and a solution is appreciated.
My code is as follows
import java.io.*;
public class convert {
public static void main(String[] args) {
//create file object
File file = new File("B:/music/Billa.mp4");
try
{
//create FileInputStream object
FileInputStream fin = new FileInputStream(file);
byte fileContent[] = new byte[(int)file.length()];
fin.read(fileContent);
//create string from byte array
String strFileContent = new String(fileContent);
System.out.println("File content : ");
System.out.println(strFileContent);
File dest=new File("B://music//a.mp4");
BufferedWriter bw=new BufferedWriter(new FileWriter(dest));
bw.write(strFileContent+"\n");
bw.flush();
}
catch(FileNotFoundException e)
{
System.out.println("File not found" + e);
}
catch(IOException ioe)
{
System.out.println("Exception while reading the file " + ioe);
}
}
}
This question might be dead but someone might find this useful.
You can't handle video as string. This is the correct way to read and write (copy) any file using Java 7 or higher.
Please note that size of buffer is processor-dependent and usually should be a power of 2. See this answer for more details.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class FileCopy {
public static void main(String args[]) {
final int BUFFERSIZE = 4 * 1024;
String sourceFilePath = "D:\\MyFolder\\MyVideo.avi";
String outputFilePath = "D:\\OtherFolder\\MyVideo.avi";
try(
FileInputStream fin = new FileInputStream(new File(sourceFilePath));
FileOutputStream fout = new FileOutputStream(new File(outputFilePath));
){
byte[] buffer = new byte[BUFFERSIZE];
while(fin.available() != 0) {
bytesRead = fin.read(buffer);
fout.write(buffer, 0, bytesRead);
}
}
catch(Exception e) {
System.out.println("Something went wrong! Reason: " + e.getMessage());
}
}
}
Hope this also helpful for you - This can read and write a file into another file (You can use any file type to do that)
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class Copy {
public static void main(String[] args) throws Exception {
FileInputStream input = new FileInputStream("input.mp4"); //input file
byte[] data = input.readAllBytes();
FileOutputStream output = new FileOutputStream("output.mp4"); //output file
output.write(data);
output.close();
}
}
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import javax.imageio.ImageIO;
public class Reader {
public Reader() throws Exception{
File file = new File("C:/Users/Digilog/Downloads/Test.mp4");
FileInputStream fin = new FileInputStream(file);
byte b[] = new byte[(int)file.length()];
fin.read(b);
File nf = new File("D:/K.mp4");
FileOutputStream fw = new FileOutputStream(nf);
fw.write(b);
fw.flush();
fw.close();
}
}
In addition to Jakub Orsula's answer, one needs to check the result of read operation to prevent garbage being written to end of file in last iteration.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class FileCopy {
public static void main(String args[]) {
final int BUFFERSIZE = 4 * 1024;
String sourceFilePath = "D:\\MyFolder\\MyVideo.avi";
String outputFilePath = "D:\\OtherFolder\\MyVideo.avi";
try(
FileInputStream fin = new FileInputStream(new File(sourceFilePath));
FileOutputStream fout = new FileOutputStream(new File(outputFilePath));
){
byte[] buffer = new byte[BUFFERSIZE];
int bytesRead;
while(fin.available() != 0) {
bytesRead = fin.read(buffer);
fout.write(buffer, 0, bytesRead);
}
}
catch(Exception e) {
System.out.println("Something went wrong! Reason: " + e.getMessage());
}
}
}
I'm creating a server/client model to send an image file from the server to the client. There's only ONE socket involved (all data are sent through it).
The server first sends the size of the image file, then sends the file data in bytes through a BufferedOutputStream.
The client first receives the size of the file(size), creates a byte[size] imageBytes, then writes the received file data into imageBytes through a BufferedInputStream.
Seems straight forward. The trouble happens when I send file size in different ways.
Way 1: using DataOutputStream and DataInputStream to send and receive file size as int.
Way 2: using a PrintWriter to println(file size), then flush; using a BufferedReader to readLine().
Way 1 works fine. But Way 2 sends the image file incorrectly.
I wonder if this is because BufferedReader still keeps its buffer after reading, and the buffer is subsequently read by the BuffereInputStream.
Here are the codes:
Server:
package test;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class TestServer {
public static void main(String[] args){
try {
ServerSocket serverSocket = new ServerSocket(9090);
Socket ss = serverSocket.accept();
System.out.println("Client connected!");
File file = new File("ServerFiles/Songs/Covers/album1.jpg"); //Change this path to your own path
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
byte[] imageBytes = new byte[(int) file.length()];
bis.read(imageBytes);
bis.close();
//Way 1-------------------------------------------------------------
DataOutputStream dos = new DataOutputStream(ss.getOutputStream());
dos.writeInt((int) file.length());
System.out.println("dos wrote "+file.length());
//End Way 1---------------------------------------------------------
//Way 2-------------------------------------------------------------
// PrintWriter pw = new PrintWriter(ss.getOutputStream());
// pw.println(file.length());
// pw.flush();
// System.out.println("pw flushed!");
//End Way 2---------------------------------------------------------
BufferedOutputStream bos = new BufferedOutputStream(ss.getOutputStream());
bos.write(imageBytes);
bos.flush();
System.out.println("bos flushed!");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Client:
package test;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class TestClient extends JFrame{
Socket cs;
ImageIcon imageIcon;
public static void main(String[] args){
try {
Socket socket = new Socket(InetAddress.getLocalHost(), 9090);
new TestClient(socket);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public TestClient(Socket cs) throws IOException{
this.cs = cs;
init();
}
private void init() throws IOException{
imageIcon = getImageIcon();
JLabel jl = new JLabel(imageIcon);
JPanel content = (JPanel) this.getContentPane();
content.add(jl);
this.setSize(600,400);
this.setVisible(true);
}
private ImageIcon getImageIcon() throws IOException{
//Way 1-------------------------------------------------------------
DataInputStream dis = new DataInputStream(cs.getInputStream());
int size = dis.readInt();
System.out.println("size="+size);
//End Way 1---------------------------------------------------------
//Way 2-------------------------------------------------------------
// BufferedReader br = new BufferedReader(new InputStreamReader(cs.getInputStream()));
// int size = Integer.parseInt(br.readLine());
// System.out.println("size="+size); //Print size
//End Way 2---------------------------------------------------------
BufferedInputStream bis = new BufferedInputStream(cs.getInputStream());
System.out.println("bis.available()="+bis.available()); //Print bis.available()
byte[] imageBytes = new byte[size];
bis.read(imageBytes);
return new ImageIcon(imageBytes);
}
}
Outputs:
Way 1:
Server:
Client connected!
dos wrote 23215
bos flushed!
Client:
size=23215
bis.available()=23215
Way 2:
Server:
Client connected!
pw flushed!
bos flushed!
Client:
size=23215
bis.available()=6837
I'd say the difference comes from DataOutputStream writing the integer in binary format, i.e. it splits the integer into 4 bytes and writes those, whereas the PrintWriter does String.valueOf(paramInt) and thus would send the bytes of the string "23215" to the client.
Since you're already sending binary data (the image), why don't you stick to way 1? You'd normally not need the header to be human readable.
There is no contract on input streams that say you will get all the data in one read. You need to keep looping on available() until it returns a negative number. Modify your code to do this and then compare your two scenarios again.