Reputation: 55
I am trying to write a java code to save data from a "For Loop" (2d array named "arr") into a compressed ".txt" file.
FileOutputStream fos = new FileOutputStream(path to zip file);
ZipOutputStream zipOut = new ZipOutputStream(new BufferedOutputStream(fos));
ZipEntry ze = new ZipEntry(path txt file);
zipOut.putNextEntry(ze);
for (int r = 0; r < 1048577; r++) {
for (int c = 0; c < 25; c++) {
zipOut.write(arr[r][c] + ","); // how do I write this line?
}
zipOut.write("\n"); // how do I write this line?
}
zipOut.closeEntry();
zipOut.close();
What piece of code should be added to convert the result into Bytes and then use "ZipOutputStream" to write data into a compressed ".txt" file?
Thanks.
Upvotes: 0
Views: 360
Reputation: 347234
So, my "big" concern is in how you might "read" the data back in, writing it is actually relatively easy.
The following does a "basic" job, using a couple of StringJoiners
to produce a String
which can be written to the file and the a, somewhat, convoluted process to decompress it.
The problem here is, the limiting factor (for me at least), is the fact that you need to read the entire contents of the file before you can begin reconstructing it.
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.StringJoiner;
import java.util.zip.DataFormatException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
public class Test {
public static void main(String[] args) throws IOException, DataFormatException {
File targetFile = new File("Test.dat");
int[][] data = new int[][]{
{0, 1, 2, 3, 4, 5},
{6, 7, 8, 9, 10, 11}
};
StringJoiner outterJoiner = new StringJoiner("\n");
for (int[] outter : data) {
StringJoiner innerJoiner = new StringJoiner(",");
for (int value : outter) {
innerJoiner.add(Integer.toString(value));
}
outterJoiner.add(innerJoiner.toString());
}
try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(targetFile))) {
ZipEntry zipEntry = new ZipEntry("master");
zos.putNextEntry(zipEntry);
zos.write(outterJoiner.toString().getBytes());
} catch (IOException ex) {
ex.printStackTrace();
}
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(targetFile)); ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
ZipEntry zipEntry = zis.getNextEntry();
if (zipEntry != null) {
byte[] buffer = new byte[1024];
int bytesRead = -1;
while ((bytesRead = zis.read(buffer)) != -1) {
baos.write(buffer, 0, bytesRead);
}
String contents = new String(baos.toByteArray());
System.out.println(contents);
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
I'm wondering if, instead of relying on \n
as a delimiter, you used the ZipEntry
instead, this would allow you to process each individual "line" of data at a time...
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.StringJoiner;
import java.util.zip.DataFormatException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
public class Test {
public static void main(String[] args) throws IOException, DataFormatException {
File targetFile = new File("Test.dat");
int[][] data = new int[][]{
{0, 1, 2, 3, 4, 5},
{6, 7, 8, 9, 10, 11}
};
try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(targetFile))) {
for (int index = 0; index < data.length; index++) {
int[] values = data[index];
ZipEntry zipEntry = new ZipEntry("Values-" + index);
zos.putNextEntry(zipEntry);
StringJoiner joiner = new StringJoiner(",");
for (int value : values) {
joiner.add(Integer.toString(value));
}
zos.write(joiner.toString().getBytes());
}
} catch (IOException ex) {
ex.printStackTrace();
}
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(targetFile))) {
ZipEntry zipEntry = null;
while ((zipEntry = zis.getNextEntry()) != null) {
System.out.println(zipEntry.getName());
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
byte[] buffer = new byte[1024];
int bytesRead = -1;
while ((bytesRead = zis.read(buffer)) != -1) {
baos.write(buffer, 0, bytesRead);
}
String contents = new String(baos.toByteArray());
System.out.println(contents);
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
Which prints out...
Values-0
0,1,2,3,4,5
Values-1
6,7,8,9,10,11
Now, obviously, you might not know how many lines you need, where as the first example, a simple String#split
will tell you. (You could pre-read each entry, but that's double dipping)
is it possible to have ZipOutputStream save "contents" into a compressed ".txt" file called "Compressed file.txt" in a zip file "C:/Users/Username/Documents/Compressed folder.zip" ?
That's entirely up to you, if you're not concerned about reading/parse the file again, then the process can be greatly reduced (in effort and complexity).
So, the example below will write a line of content at time, so you're only ever creating a single line of text and then writing it to the ZipEntry
. The StringJoiner
makes this process SOOOO much simpler
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.StringJoiner;
import java.util.zip.DataFormatException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class Test {
public static void main(String[] args) throws IOException, DataFormatException {
File targetFile = new File("Compressed.zip");
int[][] data = new int[][]{
{0, 1, 2, 3, 4, 5},
{6, 7, 8, 9, 10, 11}
};
try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(targetFile))) {
ZipEntry zipEntry = new ZipEntry("Compressed.txt");
zos.putNextEntry(zipEntry);
for (int[] outter : data) {
StringJoiner joiner = new StringJoiner(",", "", "\n");
for (int value : outter) {
joiner.add(Integer.toString(value));
}
zos.write(joiner.toString().getBytes());
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
Upvotes: 1
Reputation: 135
Here a very basic/simplyfied idea:
var zos = new ZipOutputStream(new FileOutputStream("text.zip"));
try (zos) {
var entry = new ZipEntry("test.txt");
zos.putNextEntry(entry);
var value = 12345; // just an example, should come from array/loop
zos.write(Integer.toString(value).getBytes());
zos.write(",".getBytes());
zos.write("\n".getBytes());
zos.closeEntry();
}
you'll need to add the loop.
Note1: use variables/constants for ",".getBytes(...)
and "\n"...
Note2: using the default system charset for getBytes()
, to use a specific one, use something like getBytes(StandardCharsets.UTF_8)
Upvotes: 1
Reputation: 44
import java.util.*;
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class Main {
public static void main(String[] args) {
FileOutputStream fos = null;
ZipOutputStream zipOut = null;
ZipEntry ze = null;
try {
char[][] arr = {{'a', 'b'}, {'d', 'c'}};
fos = new FileOutputStream("a.zip");
zipOut = new ZipOutputStream(new BufferedOutputStream(fos));
ze = new ZipEntry("out.txt");
zipOut.putNextEntry(ze);
StringBuilder sb = new StringBuilder();
for (int r = 0; r < arr.length; r++) {
for (int c = 0; c < arr[0].length; c++) {
sb.append(arr[r][c]).append(",");
}
sb.append("\n"); // how do I write this line?
}
zipOut.write(sb.toString().getBytes());
zipOut.closeEntry();
zipOut.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
maybe this is useful for you
Upvotes: 1