I'm having a problem getting an array to a text file in strings.
My code so far:
public class ArrayList
{
public static void main(String[] args) throws IOException
{
int myArray [] = new int [20];
for (int i = 0 ; i < 20 ; i++) {
myArray [i] = (int) (Math.random () * 8);
System.out.print(myArray[i]);
String s1 = Arrays.toString(myArray);
System.out.println(s1);
s1 = "/Users/EricDkim/Desktop/FileIOTest/pfile.txt";
File f = new File(s1);
FileOutputStream fileOut = new FileOutputStream(f);
byte value = 0x63; //By adding 0x it reads it as hex
DataOutputStream dataOut = new DataOutputStream(fileOut);
//dataoutputstream is used to write primitive java
//data types (byte, int, char, double) and strings are to a file or a socket
dataOut.writeByte(value);
//creates 20 numbers
}
}
}
How would I use the array that i created to move it to a text file?
how about using DataOutputStream#writeInt(int):
for (int i = 0 ; i < myArray.length ; i++) {
dataOut.writeInt(myArray[i]);
}
If you want to write as text then use a BufferedWriter:
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fileOut));
for (int i = 0 ; i < myArray.length ; i++) {
bw.write(Integer.toString(myArray[i]));
}
bw.close();
Don't forget to close the stream/writer.
Try
File f = new File(s1);
FileOutputStream fileOut = new FileOutputStream(f);
int myArray [] = new int [20];
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fileOut));
for (int i = 0 ; i < myArray.length ; i++) {
myArray [i] = (int) (Math.random () * 8);
bw.write(Integer.toString(myArray[i]));
bw.write(',');
}
bw.close();
The content of the file will be
0,5,1,3,4,0,0,3,0,6,7,6,4,1,1,6,0,6,7,4,
or
File f = new File(s1);
FileOutputStream fileOut = new FileOutputStream(f);
int myArray [] = new int [20];
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fileOut));
for (int i = 0 ; i < myArray.length ; i++) {
myArray [i] = (int) (Math.random () * 8);
}
bw.write(Arrays.toString(myArray));
bw.close();
The content of the file will be
[3, 3, 4, 4, 6, 1, 0, 2, 3, 5, 7, 7, 0, 5, 1, 2, 0, 4, 6, 4]
Declare
File f = new File(s1);
FileOutputStream fileOut = new FileOutputStream(f);
DataOutputStream dataOut = new DataOutputStream(fileOut);
before the for loop and close tour stream at the end of loop like this dataOut.close();
For writing the contents as text check this edited code.
public class ArrayList {
public static void main(String[] args) throws IOException {
int myArray[] = new int[20];
String s1 = "/Users/EricDkim/Desktop/FileIOTest/pfile.txt";
File f = new File(s1);
Writer fileOut = new FileWriter(f);
BufferedWriter dataOut = new BufferedWriter(fileOut);
for (int i = 0; i < 20; i++) {
myArray[i] = (int) (Math.random() * 8);
// System.out.print(myArray[i]);
// String s1 = Arrays.toString(myArray);
System.out.println(s1);
byte value = 0x63; // By adding 0x it reads it as hex
// dataoutputstream is used to write primitive java
// data types (byte, int, char, double) and strings are to a file or
// a socket
fileOut.write(Arrays.toString(myArray) + "\n");
// creates 20 numbers
}
dataOut.close();
}
}
Related
Does anyone know, how to adjust TestNG's DataProvider reading from CSV-file in equal chunks, not sequentially in general?
General:
//Read data from CSV-file:
private static Object[][] getDataFromCSV(String fileNameroot) throws IOException {
List<Object[]> records = new ArrayList<>();
String record;
BufferedReader file = new BufferedReader(new InputStreamReader(new FileInputStream(fileNameroot), StandardCharsets.UTF_8));
file.readLine();
while ((record = file.readLine()) != null) {
String[] fields = record.split(", |,");
records.add(fields);
}
file.close();
Object[][] results = new Object[records.size()][];
for (int i = 0; i < records.size(); i++) {
results[i] = records.get(i);
}
return results;
}
Say, if we have 100 rows in file, so, it should (i.e. in 10 threads) for each thread read
firstly 1, 11, 21, ..., 91 rows
then 2, 12, 22, ..., 92
and so on...
till all 100 read
UPD:
Currently, only simultaneous 2-way file read (forward and backward (thanks to honorable responders by How to read file from end to start (in reverse order) in Java?)) achieved to meet each other near the middle of the file:
//2-way read data from CSV-file:
private static Object[][] getDataFromCSV(String fileNameroot) throws IOException {
List<Object[]> records = new ArrayList<>();
String record;
String recordReversed;//
long lineCount, lineCountMiddle, curr = 0, currReversed = 0, overlap = 1;
try (Stream<String> stream = Files.lines(Path.of(fileNameroot), StandardCharsets.UTF_8)) {
lineCount = stream.count();
lineCountMiddle = (long) Math.ceil(((double)lineCount)/2d) + overlap;
System.out.println("lineCount = "+ lineCount +",\n lineCountMiddle = "+ lineCountMiddle);
}
BufferedReader file = new BufferedReader(new InputStreamReader(new FileInputStream(fileNameroot), StandardCharsets.UTF_8));
BufferedReader fileReversed = new BufferedReader(new InputStreamReader(new ReverseLineInputStream(new File(fileNameroot)), StandardCharsets.UTF_8));//Important! got from: https://stackoverflow.com/q/8664705/11714800
while (curr < lineCountMiddle && currReversed < lineCountMiddle) {
record = file.readLine();
recordReversed = fileReversed.readLine();
String[] fields = record.split("[,]\\s?|,");
String[] fieldsReversed = recordReversed.split("[,]\\s?|,");
records.add(fields);
records.add(fieldsReversed);
++curr;
++currReversed;
}
file.close();
fileReversed.close();//
Object[][] results = new Object[records.size()][];
for (int i = 0; i < records.size(); i++) {
results[i] = records.get(i);
}
return results;
}
Here, I am reading the 18 MB file and store it in a two dimensional array. But this program takes almost 15 minutes to run. Is there anyway to optimize the running time of the program. The file contains only binary values. Thanks in advanceā¦
public class test
{
public static void main(String[] args) throws FileNotFoundException, IOException
{
BufferedReader br;
FileReader fr=null;
int m = 2160;
int n = 4320;
int[][] lof = new int[n][m];
String filename = "D:/New Folder/ETOPOCHAR";
try {
Scanner input = new Scanner(new File("D:/New Folder/ETOPOCHAR"));
double range_km=1.0;
double alonn=-57.07; //180 to 180
double alat=38.53;
while (input.hasNextLine()) {
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
try
{
lof[j][i] = input.nextInt();
System.out.println("value[" + j + "][" + i + "] = "+ lof[j][i]);
}
catch (java.util.NoSuchElementException e) {
// e.printStackTrace();
}
}
} //print the input matrix
}
I have also tried with byte array but i can not save it in twoD array...
public class FileToArrayOfBytes
{
public static void main( String[] args )
{
FileInputStream fileInputStream=null;
File file = new File("name of file");
byte[] bFile = new byte[(int) file.length()];
try {
//convert file into array of bytes
fileInputStream = new FileInputStream(file);
fileInputStream.read(bFile);
fileInputStream.close();
for (int i = 0; i < bFile.length; i++) {
System.out.print((char)bFile[i]);
}
System.out.println("Done");
}catch(Exception e){
e.printStackTrace();
}
}
}
You can read the file into a byte array first, then deserialize these bytes. Start with 2048 bytes buffer (as input buffer), then experiment by increasing/decreasing its size, but the experimental buffer size values should be a power of two (512, 1024, 2048, etc).
As far as I rememenber, there are good chances that the best performance can be achived with a buffer of size 2048 bytes, but it is OS dependent and should be verified.
Code sample (here you can try different values of BUFFER_SIZE variable, in my case I've read a test file of size 7.5M in less then one second):
public static void main(String... args) throws IOException {
File f = new File(args[0]);
byte[] buffer = new byte[BUFFER_SIZE];
ByteBuffer result = ByteBuffer.allocateDirect((int) f.length());
try (FileInputStream fos = new FileInputStream(f)) {
int bytesRead;
int totalBytesRead = 0;
while ((bytesRead = fos.read(buffer, 0, BUFFER_SIZE)) != -1) {
result.put(buffer, 0, bytesRead);
totalBytesRead += bytesRead;
}
// debug info
System.out.printf("Read %d bytes\n", totalBytesRead);
// Here you can do whatever you want with the result, including creation of a 2D array...
int pos = result.position();
result.rewind();
for (int i = 0; i < pos / 4; i++) {
System.out.println(result.getInt());
}
}
}
Take your time and read docs for java.io, java.nio packages as well as Scanner class, just to improve understanding.
I am trying to create a program which would replace random number of characters at random position with "*". Star is letter used in main program and it is replaced with "." a wildcard to matches any possible result.
So far I manage to create the code you see bellow. It replaces exactly 1 character of specific word.
Any help from here on now would be much appreciated.
EXAMPLE:
Input word: MOUSE
RANDOM GENERATOR for how much characters to replace: 3
RANDOM GENERATOR at which places to replace: 1, 3, 5
RESULT: *O*S*
public class random_2 {
public static void main(String[] args) {
String test;
int dolzina = 0;
String outputFile = "random_2.txt";
ArrayList<String> list = new ArrayList();
try {
File file = new File("random1.txt");
FileReader fileReader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(fileReader);
String vrstica;
while ((vrstica = bufferedReader.readLine()) != null) {
list.add(vrstica);
// dolzina=list.size();
// System.out.println(dolzina);
}
FileWriter fileWriter = new FileWriter(outputFile);
PrintWriter out = new PrintWriter(fileWriter);
for (int idx = 0; idx <= list.size(); ++idx) {
test=list.get(idx);
dolzina=test.length();
Random rGenerator = new Random();
for (int i = 0; i<= dolzina; ++i) {
int randomInt = rGenerator.nextInt(dolzina);
StringBuilder beseda = new StringBuilder(test);
beseda.setCharAt(randomInt, '*');
System.out.println(beseda);
dolzina=0;
}}
System.out.println("Done.");
} catch (IOException e) {
e.printStackTrace();
}
}
}
Modified your code and its working:
try {
File file = new File("random1.txt");
FileReader fileReader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(fileReader);
String vrstica = bufferedReader.readLine();
while (vrstica != null) {
list.add(vrstica);
vrstica = bufferedReader.readLine();
// dolzina=list.size();
// System.out.println(dolzina);
}
FileWriter fileWriter = new FileWriter(outputFile);
PrintWriter out = new PrintWriter(fileWriter);
for (int idx = 0; idx < list.size(); ++idx) {
test = list.get(idx);
dolzina = test.length();
Random rGenerator = new Random();
StringBuilder beseda = new StringBuilder(test);
for (int i = 0; i < dolzina; ++i) {
int randomInt = rGenerator.nextInt(dolzina);
beseda.setCharAt(randomInt, '*');
System.out.println(beseda);
}
out.print(beseda);
out.close();
}
you can try something like this:
String mask(String s, int charsToMask){
if(s.length() < charsToMask) throw new IllegalArgumentException();
List<Integer> shuffle = new ArrayList<>(s.length())
for (int i = 0; i < s.length(); i++) {
shuffle.add(i, i);
}
Collections.shuffle(shuffle);
StringBuilder sb = new StringBuilder(s)
for (int i = 0; i < charsToMask; i++) {
sb.setCharAt(shuffle.get(i).intValue(), (char)'*')
}
return sb.toString()
}
print mask("MOUSE", 3)
This question already has answers here:
Convert a string representation of a hex dump to a byte array using Java?
(25 answers)
Closed 5 years ago.
I have a requirement to read a Hex String with leading zeros which represents a JPEG file, from an xml file received and save it as an image file. The image data looks like
0000005000000050FF191818FF151715FF111413FF0E1...........................FF2A2322FF292221
In xml file The length of String between the tag is 51216 I read the Hex data in between the Photo tag as a String and Converted it to a byte[], and the using a FileOutputStream I am writing to a file. But when I try to open the image file it tells "the file appears to be damaged,corrupted or file is too large" I have tried many methods to save the image, but no success. I am listing the methods used below. Please help me out from this.
String photo="0000005000000050FF191818FF15"; //this is just a sample.The photo String actually contains the full Hex String which is 51216 long
//METHOD 1
String[] v = photo.split(" ");
byte[] arr = new byte[v.length];
int x = 0;
for(String val: v) {
arr[x++] = Integer.decode("0x" + val).byteValue();
}
FileOutputStream fos=new FileOutputStream("D:/Images/image6.jpg");
fos.write(arr);
fos.flush();
fos.close();
//METHOD 2
byte[] arr = new byte[photo.length()/2];
for ( int start = 0; start < photo.length(); start += 2 )
{
String thisByte = photo.substring(start, start+2);
arr[start/2] = Byte.parseByte(thisByte, 16);
}
FileOutputStream fos=new FileOutputStream("D:/Images/image6.jpg");
fos.write(arr);
fos.flush();
fos.close();
//METHOD 3
if ((photo.length() % 2) != 0)
throw new IllegalArgumentException("Input string must contain an even number of characters");
final byte result[] = new byte[photo.length()/2];
final char enc[] = photo.toCharArray();
for (int x = 0; x < enc.length; x += 2)
{
StringBuilder curr = new StringBuilder(2);
curr.append(enc[x]).append(enc[x + 1]);
result[x/2] = (byte) Integer.parseInt(curr.toString(), 16);
}
FileOutputStream fos=new FileOutputStream("D:/Images/image6.jpg");
fos.write(result);
fos.flush();
fos.close();
//METHOD 4
byte result[] = new byte[photo.length()/2];
char enc[] = photo.toUpperCase().toCharArray();
StringBuffer curr;
for (int x = 0; x < enc.length; x += 2)
{
curr = new StringBuffer("");
curr.append(String.valueOf(enc[x]));
curr.append(String.valueOf(enc[x + 1]));
result[x] = (byte) Integer.parseInt(curr.toString(), 16);
}
FileOutputStream fos=new FileOutputStream("D:/Images/image6.jpg");
fos.write(result);
fos.flush();
fos.close();
//METHOD 5
int len = photo.length();
byte[] data = new byte[len / 2];
for (int x = 0; x < len; x += 2)
{
data[x / 2] = (byte) ((Character.digit(photo.charAt(x), 16) << 4)
+ Character.digit(photo.charAt(x+1), 16));
}
FileOutputStream fos=new FileOutputStream("D:/Images/image6.jpg");
fos.write(data);
fos.flush();
fos.close();
//METHOD 6
byte[] bytes=new BigInteger(photo, 16).toByteArray();
FileOutputStream fos=new FileOutputStream("D:/Images/image6.jpg");
fos.write(bytes);
fos.flush();
fos.close();
//METHOD 7
byte[] bytes =DatatypeConverter.parseHexBinary(photo);
FileOutputStream fos=new FileOutputStream("D:/Images/image6.jpg");
fos.write(bytes);
fos.flush();
fos.close();
//METHOD 8
HexBinaryAdapter adapter = new HexBinaryAdapter();
byte[] bytes = adapter.unmarshal(photo);
FileOutputStream fos=new FileOutputStream("D:/Images/image6.png");
fos.write(bytes);
fos.flush();
fos.close();
//METHOD 9
byte data[] = new byte[photo.length()/2];
for(int x=0;i < photo.length();x+=2) {
data[x/2] = (Integer.decode("0x"+photo.charAt(x)+photo.charAt(x+1))).byteValue();
}
FileOutputStream fos=new FileOutputStream("D:/Images/image6.jpg");
fos.write(data);
fos.flush();
fos.close();
//METHOD 10
byte[] data = new byte[photo.length()/2];
for (int x=0;i<photo.length()/2;x++)
{
data[x] = (Integer.decode(
"0x"+photo.substring(x*2, (x+1)*2))).byteValue();
}
FileOutputStream fos=new FileOutputStream("D:/Images/image6.jpg");
fos.write(data);
fos.flush();
fos.close();
//METHOD 11
String hexVal ="0000005000000050FF";
//String hexVal = "0123456789ABCDEF";
byte[] out = new byte[photo.length() / 2];
int n = photo.length();
for( int x = 0; x < n; x += 2 ) {
int hn = hexVal.indexOf( photo.charAt( x ) );
int ln = hexVal.indexOf( photo.charAt( x + 1 ) );
out[x/2] = (byte)( ( hn << 4 ) | ln );
}
FileOutputStream fos=new FileOutputStream("D:/Images/image6.jpg");
fos.write(out);
fos.flush();
fos.close();
//METHOD 12
byte[] array=photo.getBytes();
FileOutputStream fos=new FileOutputStream("D:/Images/image6.jpg");
fos.write(array);
fos.flush();
fos.close();
//METHOD 13
byte[] array=photo.getBytes();
byte[] bytes = Base64.decode(array);
FileOutputStream fos=new FileOutputStream("D:/Images/image6.jpg");
fos.write(bytes);
fos.flush();
fos.close();
//METHOD 14
byte[] array=photo.getBytes();
Charset csets = Charset.forName("UTF-8");
ByteBuffer bb=ByteBuffer.wrap(array);
csets.decode(bb);
bb.rewind();
byte[] array1=bb.array();
FileOutputStream fos=new FileOutputStream("D:/Images/image6.jpg");
fos.write(array1);
fos.flush();
fos.close();
The shortest way might be this.
String photo = "0000005000000050FF191818FF151715FF111413FF0E100FF2A2322FF292221";
// adds a dummy byte at the start to avoid truncation of leading zeros.
byte[] bytes = new BigInteger("10" + photo, 16).toByteArray();
System.out.println(Arrays.toString(bytes));
prints
[1, 0, 0, 0, 5, 0, 0, 0, 5, 15, -15, -111, -127, -113, -15, 81, 113, 95, -15, 17, 65, 63, -16, -31, 0, -1, 42, 35, 34, -1, 41, 34, 33]
public class test {
static String HEX_STRING = "0123456789ABCDEF";
public static byte[] convertHexadecimal2Binary(byte[] hex) {
int block = 0;
byte[] data = new byte[hex.length / 2];
int index = 0;
boolean next = false;
for (int i = 0; i < hex.length; i++) {
block <<= 4;
int pos = HEX_STRING.indexOf(Character.toUpperCase((char) hex[i]));
if (pos > -1) {
block += pos;
}
if (next) {
data[index] = (byte) (block & 0xff);
index++;
next = false;
} else {
next = true;
}
}
return data;
}
public static void main(String args[]) {
String line = "";
String line_final = "";
try {
String sCurrentLine;
BufferedReader br = new BufferedReader(new FileReader("D:\\test.txt"));//test.txt hex code string
DataOutputStream os = new DataOutputStream(new FileOutputStream("D:\\mohit.jpg"));
while ((sCurrentLine = br.readLine()) != null) {
line = StringUtils.deleteWhitespace(sCurrentLine);
byte[] temp = convertHexadecimal2Binary(line.getBytes());
os.write(temp);
}
os.close();
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
When you retrieve a file a space will be appended at the beginning of the hex string so remove the space and store it in another byte array and it works fine:
here is code for removing starting space
byte a3[] = new BigInteger(str, 16).toByteArray();
byte a[] = new byte[a3.length - 1];
for (int i = 1; i < a3.length; i++)
a[i - 1] = a3[i];
Here a3 contains retrieved byte data;
a1 contains actual byte stream
Method 2 looks correct (haven't checked all others) -- your problem is probably elsewhere. Are you sure the string extracted from the XML is complete? Which parser are you using? Perhaps it returns long strings in multiple parts (I think this might be the case for SAX parsers), and you are extracting only the first part?
Here is how I would implement the decoding part (avoiding unneeded extra allocations via substring, BigInteger, char[] etc...; for performance, you may want to use a BufferedOutputStream though):
String photo = "0000005000000050FF191818FF15";
FileOutputStream fos = new FileOutputStream("D:/Images/image6.jpg");
for (int i = 0; i < photo.length; i += 2) {
int byte = Character.digit(photo.charAt(i), 16) * 16 +
Character.digit(photo.charAt(i + 1), 16);
fos.write(byte);
}
fos.close();
PrintWriter fout = new PrintWriter(new BufferedWriter(
new FileWriter("numbers.dat")
));
for(int i = start; i <= 100; i = i + 2) {
fout.print(i + ", ");
}
Right now my output is like this:
2, 4, 6, 8, 10,
What I want:
2, 4, 6, 8, 10
Here's a neat way of doing it:
PrintWriter fout = new PrintWriter(new BufferedWriter(
new FileWriter("numbers.dat")
));
String sep = "";
for(int i = start; i <= 100; i += 2) {
fout.print(sep + i);
sep = ", ";
}
Here's another way:
PrintWriter fout = new PrintWriter(new BufferedWriter(
new FileWriter("numbers.dat")
));
for(int i = start; i <= 100; i += 2) {
fout.print((i == start ? "" : ", ") + i);
}
Without being too sure of the function of PrintWriter, it may be more efficient to produce the string with a StringBuffer first:
PrintWriter fout = new PrintWriter(new BufferedWriter(
new FileWriter("numbers.dat")
));
StringBuffer buffer;
for(int i = start; i <= 100; i += 2) {
buffer.append(i == start ? "" : ", ").append(i);
}
fout.print(buffer);
Or more efficiently still:
PrintWriter fout = new PrintWriter(new BufferedWriter(
new FileWriter("numbers.dat")
));
StringBuffer buffer;
for(int i = start; i <= 100; i += 2) {
buffer.append(i).append(", ");
}
buffer.setLength(buffer.length()-1);
fout.print(buffer);
Print the first number and then print "," + number afterwards. Starting from i = start + 2;
try this:
PrintWriter fout = new PrintWriter(new BufferedWriter(new FileWriter("numbers.dat")));
for(int i = start; i <= 100; i += 2) {
if(i + 2 <= 100)
fout.print(i+",");
}
Do something like -
fout.print(i);
if (i < 100) {
fout.print(",");
}
Or write to a StringBuffer and delete trailing comma after the loop
StringBuffer sb = new StringBuffer();
for(...){
...
}
sb.deleteCharAt(sb.length() -1);
fout.print(sb.toString());
Hope this helps!