I have a problem with binary type. I have binary file with data. Every element is split by "_". I am using
DataInputStream in = new DataInputStream(new FileInputStream("C:/Data/"+names)); , where names is the name of my binary file. How I can read this file and saving elements in array? This is possible?
When writing to a binary file, there is no need to split each items in the matrix with '_'. The program knows how many bytes allocated for each item.
The following code write 2 doubles without '_' in between. After that, it reads them back from the file and output the data.
public class Test {
public static void main(String[] args) throws Exception {
DataOutputStream dos = new DataOutputStream(new FileOutputStream("a.bin"));
dos.writeDouble(1.2);
dos.writeDouble(3.4);
dos.close();
DataInputStream dis = new DataInputStream(new FileInputStream("a.bin"));
System.out.println(dis.readDouble());
System.out.println(dis.readDouble());
dis.close();
}
}
The program outputs:
1.2
3.4
But if you didn't write the file and there is '_' between items, you can use readChar() after reading each item from the binary file as #Bhaskar already mentioned.
Finally, using ObjectOutputStream can write the whole array at once.
public class Test {
public static void main(String[] args) throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.bin"));
double[] a = {1.2, 3.4};
oos.writeObject(a);
oos.close();
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.bin"));
double[] b = (double[]) ois.readObject();
System.out.println(b[0]);
System.out.println(b[1]);
ois.close();
}
}
It depends on how the data was written down into that file. If it was written using DataOutputStream's writeXXX() where XXX stands for the actual data type of elements, and where elements were separated by a writeChar('_') , then you can easily read them back using DataInputStream's readXXX() method. Just make sure that you read the elements in the exact sequence that they were written , and also that you use readChar() whenever you expect the - to be present ( ie between two elements).
You can use read(byte[]) or read(byte[],ffset,length) to read the content of file into byte array.
Related
My code is working. I just need to know about the role of a specific variable in the code.
I tried to print the value in the variable "data", but it gives me some numbers i cant understand.
public static void main(String[] args) throws IOException {
FileInputStream fileinputstream = new FileInputStream ("c:\\Users\\USER\\Desktop\\read.TXT");
FileOutputStream fileoutputstream = new FileOutputStream("c:\\Users\\USER\\Desktop\\write.TXT");
while (fileinputstream.available() > 0) {
int data = fileinputstream.read();
fileoutputstream.write(data);
}
fileinputstream.close();
fileoutputstream.close();
}
You can look at the docs for FileInputStream.read, which says:
Reads a byte of data from this input stream. This method blocks if no input is yet available.
Returns:
the next byte of data, or -1 if the end of the file is reached.
So the integer you got (i.e. the number stored in data) is the byte read from the file. Since your file is a text file, it is the ASCII value of the characters in that file (assuming your file is encoded in ASCII).
FileInputStream#read() reads a single byte of information from the underlying file.
Since these files are text files (according to their extensions), you probably should be using a FileInputStream, but a FileReader, to properly handle characters, and not the bytes that make them up.
fileinputstream.read() returns "the next byte of data, or -1 if the end of the file is reached."
You can read more here
In another word, the file was write with PCM_16bit, but those data was store as 8-bit. I want to ananlyze this file with dsp, but how can I read this file in 16 bit a time and form this 16bit as one integer from 0-65535.
Not entirely sure what you're asking, but if what you want is to read two-bytes at a time as a single unsigned value, you can use something like this:
File f = new File("/path/to/file");
DataInputStream dis = new DataInputStream(new FileInputStream(f));
List<Integer> values = new ArrayList<>();
try {
while (true){
values.add(dis.readUnsignedShort());
}
} catch(EOFException e){
/* you've read everything at this point */
} finally {
dis.close();
}
You can change values into a primitive array at that point, or just work with the list directly.
This is my encryption program. Primarily used to encrypt Files(text)
This part of the program converts List<Integer> elements intobyte [] and writes it into a text file. Unfortunately i cannot provide the algorithm.
void printit(List<Integer> prnt, File outputFile) throws IOException
{
StringBuilder building = new StringBuilder(prnt.size());
for (Integer element : prnt)
{
int elmnt = element;
//building.append(getascii(elmnt));
building.append((char)elmnt);
}
String encryptdtxt=building.toString();
//System.out.println(encryptdtxt);
byte [] outputBytes = offo.getBytes();
FileOutputStream outputStream =new FileOutputStream(outputFile);
outputStream.write(outputBytes);
outputStream.close();
}
This is the decryption program where the decryption program get input from a .enc file
void getfyle(File inputFile) throws IOException
{
FileInputStream inputStream = new FileInputStream(inputFile);
byte[] inputBytes = new byte[(int)inputFile.length()];
inputStream.read(inputBytes);
inputStream.close();
String fylenters = new String(inputBytes);
for (char a:fylenters.toCharArray())
{
usertext.add((int)a);
}
for (Integer bk : usertext)
{
System.out.println(bk);
}
}
Since the methods used here, in my algorithm require List<Integer> byte[] gets converted to String first and then to List<Integer>and vice versa.
The elements while writing into a file during encryption do not match the elements read from the .enc file.
Is my method of converting List<Integer> to byte[] correct??
or is something else wrong? . I do know that java can't print extended ASCII characters so i used this .But, even this failed.It gives a lot of ?s
Is there a solution??
please help me .. and also how to do it for other formats(.png.mp3....etc)
The format of the encrypted file can be anything (it needn't be .enc)
thanxx
There are thousands of different 'extended ASCII' codes and Java supports about a hundred of them,
but you have to tell it which 'Charset' to use or the default often causes data corruption.
While representing arbitrary "binary" bytes in hex or base64 is common and often necessary,
IF the bytes will be stored and/or transmitted in ways that preserve all 256 values, often called "8-bit clean",
and File{Input,Output}Stream does, you can use "ISO-8859-1" which maps Java char codes 0-255 to and from bytes 0-255 without loss, because Unicode is based partly on 8859-1.
on input, read (into) a byte[] and then new String (bytes, charset) where charset is either the name "ISO-8859-1"
or the java.nio.charset.Charset object for that name, available as java.nio.charset.StandardCharSets.ISO_8859_1;
or create an InputStreamReader on a stream reading the bytes from a buffer or directly from the file, using that charset name or object, and read chars and/or a String from the Reader
on output, use String.getBytes(charset) where charset is that charset name or object and write the byte[];
or create an OutputStreamWriter on a stream writing the bytes to a buffer or the file, using that charset name or object, and write chars and/or String to the Writer
But you don't actually need char and String and Charset at all. You actually want to write a series of Integers as bytes, and read a series of bytes as Integers. So just do that:
void printit(List<Integer> prnt, File outputFile) throws IOException
{
byte[] outputBytes = new byte[prnt.size()]; int i = 0;
for (Integer element : prnt) outputBytes[i++] = (byte)element;
FileOutputStream outputStream =new FileOutputStream(outputFile);
outputStream.write(b);
outputStream.close();
// or replace the previous three lines by one
java.nio.file.Files.write (outputFile.toPath(), outputBytes);
}
void getfyle(File inputFile) throws IOException
{
FileInputStream inputStream = new FileInputStream(inputFile);
byte[] inputBytes = new byte[(int)inputFile.length()];
inputStream.read(inputBytes);
inputStream.close();
// or replace those four lines with
byte[] inputBytes = java.nio.file.Files.readAllBytes (inputFile.toPath());
for (byte b: inputBytes) System.out.println (b&0xFF);
// or if you really wanted a list not just a printout
ArrayList<Integer> list = new ArrayList<Integer>(inputBytes.length);
for (byte b: inputBytes) list.add (b&0xFF);
// return list or store it or whatever
}
Arbitrary data bytes are not all convertible to any character encoding and encryption creates data bytes including all values 0 - 255.
If you must convert the encrypted data to a string format the standard methods are to convert to Base64 or hexadecimal.
In encryption part:
`for (Integer element : prnt)
{
int elmnt = element;
//building.append(getascii(elmnt));
char b = Integer.toString(elmnt).charAt(0);
building.append(b);
}`
-->this will convert int to char like 1 to '1' and 5 to '5'
I have an assignment to write some numbers in a text file using PrintStream and then reading from that same file using RandomAccessFile. While the writing part works as intended, I get the following output when running my code.
807416096
840971040
874525984
Exception in thread "main" java.io.EOFException
908080928
941635872
at java.io.RandomAccessFile.readInt(RandomAccessFile.java:776)
at Problema4.main(Problema4.java:21)
Java Result: 1
Here is the code:
import java.io.*;
import java.util.*;
public class Problema4 {
public static void main(String[] args) throws IOException, FileNotFoundException
{
PrintStream ps = new PrintStream(new FileOutputStream("fisiernou.txt"));
int i=0;
while (i<11)
{
ps.print(i);
ps.print(" ");
i++;
}
ps.close();
RandomAccessFile raf = new RandomAccessFile("fisiernou.txt", "r");
raf.seek(0);
//System.out.println(raf.readInt());
while (raf.getFilePointer()<raf.length())
System.out.println(raf.readInt());
raf.close();
}
}
You are writing integer as strings ( ps.print(i) ). If you write 1, in the file you are writting the ascii character of 1. Suposse this is the unique number we write, the file then have only one byte.
When reading, you are using raf.readInt(). This method reads 4 bytes and convert them to an integer. If now you try to read your file, this only contains one byte (the ascii character of 1), and then you get an EOF excepcion.
Use the same type of method for writting and reading. You can write with FileOutputStream.write(int).
RandomAccessFile.readInt() reads a binary 32-bit integer from the file. This means that it read 4 bytes and transform those 4 bytes into an int. It doesn't read the string representation of an int. Read its javadoc.
When your raf pointer is reading from the file, it is possible to hit an 'End of File' character. From the Java API:
"It is generally true of all the reading routines in this class that if end-of-file is reached before the desired number of bytes has been read, an EOFException (which is a kind of IOException) is thrown."
http://docs.oracle.com/javase/7/docs/api/java/io/RandomAccessFile.html
How can I write/read a string from a binary file?
I've tried using writeUTF / readUTF (DataOutputStream/DataInputStream) but it was too much of a hassle.
Thanks.
Forget about FileWriter, DataOutputStream for a moment.
For binary data one uses OutputStream and InputStream classes. They handle byte[].
For text data one uses Reader and Writer classes. They handle String which can store all kind of text, as it internally uses Unicode.
The crossover from text to binary data can be done by specifying the encoding, which defaults to the OS encoding.
new OutputStreamWriter(outputStream, encoding)
string.getBytes(encoding)
So if you want to avoid byte[] and use String you must abuse an encoding which covers all 256 byte values in any order. So no "UTF-8", but maybe "windows-1252" (also named "Cp1252").
But internally there is a conversion, and in very rare cases problems might happen. For instance é can in Unicode be one code, or two, e + combining diacritical mark right-accent '. There exists a conversion function (java.text.Normalizer) for that.
One case where this already led to problems is file names in different operating systems; MacOS has another Unicode normalisation than Windows, and hence in version control system need special attention.
So on principle it is better to use the more cumbersome byte arrays, or ByteArrayInputStream, or java.nio buffers. Mind also that String chars are 16 bit.
If you want to write text you can use Writers and Readers.
You can use Data*Stream writeUTF/readUTF, but the strings have to be less than 64K characters long.
public static void main(String... args) throws IOException {
// generate a million random words.
List<String> words = new ArrayList<String>();
for (int i = 0; i < 1000000; i++)
words.add(Long.toHexString(System.nanoTime()));
writeStrings("words", words);
List<String> words2 = readWords("words");
System.out.println("Words are the same is " + words.equals(words2));
}
public static List<String> readWords(String filename) throws IOException {
DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(filename)));
int count = dis.readInt();
List<String> words = new ArrayList<String>(count);
while (words.size() < count)
words.add(dis.readUTF());
return words;
}
public static void writeStrings(String filename, List<String> words) throws IOException {
DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(filename)));
dos.writeInt(words.size());
for (String word : words)
dos.writeUTF(word);
dos.close();
}
prints
Words are the same is true