I have this file that I send from a server to a client through a socket. However when I try to reaad the first 159 first bytes in the client it gives a result that is smaller than when I ask the server to read the same amount in the original file, but when I print the length of what I read in both sides it is the same but one is almost 2/3 of the other! What could be the problem? I already made replaceAll("(\\r|\\n|\\s)","") to take off any space or tabulation but still no change.
Any suggestions?
Here is the code where I write the file:
FileOutputStream writer = new FileOutputStream("Splits.txt");
String output= null;
StringBuilder sb2 = new StringBuilder();
for (int i =0; i < MainClass.NUM_OF_SPLITS ; i++){
StringBuilder sb1 = new StringBuilder();
for (String s : MainClass.allSplits.get(i).blocks)
{sb2.append(s);}
sb1.append(sb2);}
output = sb2.toString().replaceAll("(\\r|\\n|\\s)", "");
writer.write(output.getBytes(Charset.forName("ISO-8859-1")));
writer.close();
And here where I read the file:
FileInputStream fis = new FileInputStream("Splits.txt");
InputStreamReader reader = new InputStreamReader(fis,Charset.forName("ISO-8859-1"));
for(int i = 0; i < splitsNum; i++) {
char[] buf = new char[159]; //param
int count = reader.read(buf);
String h=String.valueOf(buf, 0, count).replaceAll("(\\r|\\n||\\s)","");
System.out.println( h);
}
You need to loop until you've read all the data you need:
char[] buf = new char[159];
int charsRead = 0;
while (charsRead < buf.length) {
int count = reader.read(buf, charsRead, buf.length - charsRead);
if (count < 0) {
throw new EOFException();
}
charsRead += count;
}
// Right, now you know you've actually read 159 characters...
Related
everyone! I recently learned about variable byte encoding.
for example, if a file contains this sequence of number: 824 5 214577
applying variable byte encoding this sequence would be encoded as 000001101011100010000101000011010000110010110001.
Now I want to know how to write that in another file such that to produce a kind of compressed file from the original. and similarly how to read it. I'm using JAVA .
Have tried this:
LinkedList<Integer> numbers = new LinkedList<Integer>();
numbers.add(824);
numbers.add(5);
numbers.add(214577);
String code = VBEncoder.encodeToString(numbers);//returns 000001101011100010000101000011010000110010110001 into code
File file = new File("test.compressed");
DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
out.writeBytes(code);
out.flush();
this just writes the binary representation into the file..and this is not what I'm expecting.
I have also tried this:
LinkedList<Integer> code = VBEncoder.encode(numbers);//returns linked list of Byte(i give its describtion later)
File file = new File("test.compressed");
DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
for(Byte b:code){
out.write(b.toInt());
System.out.println(b.toInt());
}
out.flush();
// he goes the describtion of the class Byte
class Byte {
int[] abyte;
Byte() {
abyte = new int[8];
}
public void readInt(int n) {
String bin = Integer.toBinaryString(n);
for (int i = 0; i < (8 - bin.length()); i++) {
abyte[i] = 0;
}
for (int i = 0; i < bin.length(); i++) {
abyte[i + (8 - bin.length())] = bin.charAt(i) - 48;
}
}
public void switchFirst() {
abyte[0] = 1;
}
public int toInt() {
int res = 0;
for (int i = 0; i < 8; i++) {
res += abyte[i] * Math.pow(2, (7 - i));
}
return res;
}
public static Byte fromString(String codestring) {
Byte b = new Byte();
for(int i=0; i < 8; i++)
b.abyte[i] = (codestring.charAt(i)=='0')?0:1;
return b;
}
public String toString() {
String res = "";
for (int i = 0; i < 8; i++) {
res += abyte[i];
}
return res;
}
}
its prints this in the console:
6
184
133
13
12
177
this second attempt seems to work...the output file size is 6 bytes while for the first attemps it was 48 bytes.
but the problem in the second attempt is that I can't successfully read back the file.
InputStreamReader inStream = new InputStreamReader(new FileInputStream(file));
int c = -1;
while((c = inStream.read()) != -1){
System.out.println( c );
}
i get this:
6
184
8230
13
12
177
..so maybe I'm doing it the wrong way: expecting to receive some good advice from you. thanks!
It is solved; I was just not reading the file the right way:below is the right way:
DataInputStream inStream = null;
inStream = new DataInputStream(new BufferedInputStream(newFileInputStream(file)));
int c = -1;
while((c = inStream.read()) != -1){
Byte b = new Byte();
b.readInt(c);
System.out.println( c +":" + b.toString());
}
now I get this as the result:
6:00000110
184:10111000
133:10000101
13:00001101
12:00001100
177:10110001
Now the importance of writing the original sequence of integers into variable encoded bytes reduces the size of the file; if we normally write this sequence of integers in the file, its size would be 12 bytes (3 * 4 bytes). but now it is just 6 bytes.
int c = -1;
LinkedList<Byte> bytestream = new LinkedList<Byte>();
while((c = inStream.read()) != -1){
Byte b = new Byte();
b.readInt(c);
bytestream.add(b);
}
LinkedList<Integer> numbers = VBEncoder.decode(bytestream);
for(Integer number:numbers) System.out.println(number);
//
//here goes the code of VBEncoder.decode
public static LinkedList<Integer> decode(LinkedList<Byte> code) {
LinkedList<Integer> numbers = new LinkedList<Integer>();
int n = 0;
for (int i = 0; !(code.isEmpty()); i++) {
Byte b = code.poll();
int bi = b.toInt();
if (bi < 128) {
n = 128 * n + bi;
} else {
n = 128 * n + (bi - 128);
numbers.add(n);
n = 0;
}
}
return numbers;
}
I get back the sequence:
824
5
214577
I have a file that contains a string followed by bytes that contain binary numbers encoded in them.
Thisisastring. �J
In my code I try to ignore the string and focus on decoding the bytes that are separated by a space. When I run the code the outcome seems to be correct except the first binary number is off by a lot.
StringBuffer buffer = new StringBuffer();
File file = new File(arg);
FileInputStream in = new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(in, "UTF8");
Reader inn = new BufferedReader(isr);
int ch;
while ((ch = inn.read()) > -1){
buffer.append((char)ch);
}
inn.close();
String content = buffer.toString();
String temp = new String();
for(int i=0; i<content.length(); i++){
temp += content.charAt(i);
if(content.charAt(i) == ' '){
while(i != content.length()-1){
i++;
byte b = (byte) content.charAt(i);
String x = Integer.toString(b & 0xFF, 2);
System.out.println(x);
}
}
}
Results:
11111101 <- Why is only this one incorrect?
11000
1001010
1011
What is expected:
10010101
00011000
01001010
1011
You should not use Readers or Strings for binary data.
StringBuffer buffer = new StringBuffer();
File file = new File(arg);
FileInputStream in = new FileInputStream(file);
DataInputStream dis = new DataInputStream(new BufferedInputStream(in));
int ch;
while ((ch = din.read()) > -1){
buffer.append((char)ch);
if (ch == ' ')
{
// next byte is a binary value
byte b = din.readByte();
String x = Integer.toString(b & 0xFF, 2);
System.out.println(x);
}
}
I need to read a text file, and break the text into blocks of 6 characters (including spaces), pad zeroes to the end of text to meet the requirement.
I tried doing it and here is what I have done.
File file = new File("Sample.txt");
String line;
try {
Scanner sc = new Scanner(file);
while(sc.hasNext()){
line = sc.next();
int chunk = line.length();
int block_size=6;
if((chunk%block_size) != 0)
{
StringBuilder sb = new StringBuilder(line);
int val = chunk%block_size;
for(int i=0; i<val; i++){
sb.append(" ");
}
line = new String(sb.toString());
}
int group = line.length() / block_size;
String[] b = new String[group];
System.out.println(line);
System.out.println(chunk);
int j =0;
for(int i=0; i<group;i++){
b[i] = line.substring(j,j+block_size);
j += block_size;
}
System.out.println("String after spliting is: ");
for(int i=0; i<group;i++){
System.out.println(b[i]);
}
}
}
Now this works fine when the text in the input file has no spaces between words. But when I add spaces gives me a different output. I am stuck up at this point. Any suggestions on the same ?
I don't want to write the solution for you, but I'd advise you that what you're trying to accomplish might be easier to do using a BufferedReader with a FileReader and by using Reader.read(buf) where buf is a char[6];
I use a BufferedReader to read lines from an InputStream. When I read something directly from the InputStream, the BufferedReader ignores my read and continues reading at the same location. Is it possible to prevent this behavior? If not what is a good practice to do this?
PS: Here's my code:
byte[] ba = new byte[1024*1024];
int off = 0;
int len = 0;
do {
len = Integer.parseInt(br.readLine());
in.read(ba, off, len);
br.readLine();
off += len;
} while(len > 0);
in is my inputstream and br my bufferedreader.
If not what is a good practice to do this?
This is not a good approach to read by 2 stream at a time for same file. You have to use just one stream.
BufferedReader is used for character stream whereas InputStream is used for binary stream.
A binary stream doesn't have readLine() method that is only available in character stream.
Reading from a BufferedReader and an InputStream at the same time is not possible. If you need binary data, you should use multiple readLine() calls.
Here's my new code:
byte[] ba = new byte[1024*1024];
int off = 0;
int len = 0;
do {
len = Integer.parseInt(br.readLine().split(";" , 2)[0],16);
for (int cur = 0; cur < len;) {
byte[] line0 = br.readLine().getBytes();
for (int i = 0; i < line0.length; i++) {
ba[off+cur+i] = line0[i];
}
cur += line0.length;
if(cur < len) {
ba[off+cur] = '\n';
cur++;
}
}
off += len;
} while(len > 0);
BufferedReader bufferedReader = null;
try
{
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line = null;
while((line = bufferedReader.readLine()) != null)
{
//process lines here
}
}
catch(IOException e)
{
e.printStackTrace();
}
finally
{
if(bufferedReader != null)
{
try
{
bufferedReader.close();
}
catch(IOException e)
{
}
}
}
String str[] = {"1000458551||A210171046D86F9F6EE21B66FE9B1441E20EC1DEF9654A2D092162591C01D26F||1||7707||0||"
+ "0||1002||1373569142000||HTC One||val||4.1.2||0||1.01.20130206.15441^^1000458551||A210171046D86F9F6EE21B66FE9B1441E20EC1DEF9654A2D092162591C01D26F||"
+ "1||7707||0||0||1002||1373569142000||HTC One||val||4.1.2||0||1.01.20130206.15441","1000458551||A210171046D86F9F6EE21B66FE9B1441E20EC1DEF9654A2D092162591C01D26F||1||7707||0||"
+ "0||1002||1373569142000||HTC One||val||4.1.2||0||1.01.20130206.15441^^1000458551||A210171046D86F9F6EE21B66FE9B1441E20EC1DEF9654A2D092162591C01D26F||"
+ "1||7707||0||0||1002||1373569142000||HTC One||val||4.1.2||0||1.01.20130206.15441"};
ByteArrayOutputStream baos = new ByteArrayOutputStream();
for(String p:str){
String Recordstore[] = p.split("\\^\\^");
long len = Recordstore.length;
long counter = 0;
StringBuffer finalRecord = new StringBuffer();
for (String rec : Recordstore) {
rec = rec.replaceAll("\\|\\|", "|");
if (counter != len - 1)
finalRecord.append(rec).append(System.lineSeparator());
else
finalRecord.append(rec);
counter++;
}
baos.write(finalRecord.toString().getBytes());
}
ByteArrayInputStream object = new ByteArrayInputStream(
baos.toByteArray());
String pr="";
for(int y = 0 ; y < 1; y++ ) {
while(( c= object.read())!= -1) {
pr+=(char)c;
}
System.out.println(pr);
object.reset();
}
After converting the string to bytes and rechecking the bytes, I see that the new line character is lost and the string are combined in a single line.
How to be able to preserve the new line character even after the conversion to bytes?
Sample Output is :
adding the new line to the string and printing the string gives:
1000458551|A210171046D86F9F6EE21B66FE9B1441E20EC1DEF9654A2D092162591C01D26F|1|7707|0|0|1002|1373569142000|HTC One|val|4.1.2|0|1.01.20130206.15441
1000458551|A210171046D86F9F6EE21B66FE9B1441E20EC1DEF9654A2D092162591C01D26F|1|7707|0|0|1002|1373569142000|HTC One|val|4.1.2|0|1.01.20130206.15441
After converting it to bytes and printing the string
1000458551|A210171046D86F9F6EE21B66FE9B1441E20EC1DEF9654A2D092162591C01D26F|1|7707|0|0|1002|1373569142000|HTC One|val|4.1.2|0|1.01.20130206.154411000458551|A210171046D86F9F6EE21B66FE9B1441E20EC1DEF9654A2D092162591C01D26F|1|7707|0|0|1002|1373569142000|HTC One|val|4.1.2|0|1.01.20130206.15441
Thanks for the reply in advance
Because this line is never executed.
finalRecord.append(rec).append(System.lineSeparator());
I'm not sure why you split string like this:
String Recordstore[] = p.split("\\^\\^");
Obviously, the array Recordstore.length() will always be 1, since there isn't any ^^ in your original string.
So counter != len - 1 will always be false.
update:
I made some changes in this line:
baos.write(finalRecord.append(System.lineSeparator()).toString().getBytes());