I'm trying to restore some datafiles (mostly pdfs) from a SQL Server base.
The table column is of the following type: D_BLOB(image) and contains this type of data:
As for the code and different approaches I tried, here my different parts of code combined
byte[] output = qResult.getBytes("DOCUMENT");
Blob blob = qResult.getBlob("DOCUMENT");
String document2 = qResult.getString("DOCUMENT");
InputStream input = qResult.getBinaryStream("DOCUMENT");
FileOutputStream output2 = new FileOutputStream(new File(repertoireDst + "\\" + intitule + "_test2_." + extension));
byte[] buffer = new byte[1024];
while (input.read(buffer) > 0) {
output2.write(buffer);
}
output2.close();
/************************************
* Simple input output Stream
*******************/
InputStream inputStream = blob.getBinaryStream();
OutputStream outputStream = new FileOutputStream(repertoireDst + "\\" + intitule + "_test_." + extension);
int bytesRead = -1;
byte[] buffer2 = new byte[1024];
while ((bytesRead = inputStream.read(buffer2)) != -1) {
outputStream.write(buffer2, 0, bytesRead);
}
inputStream.close();
outputStream.close();
/************************************
* Simple byte writing
*******************/
FileOutputStream fos = null;
fos = new FileOutputStream(new File(repertoireDst + "\\" + intitule + "_V1_EcritureBytesSymple." + extension));
fos.write(output);
fos.flush();
fos.close();
/*************************************************
* Ecriture of bynary stream from blob
***********************************************/
InputStream is = blob.getBinaryStream();
FileOutputStream fos1 = new FileOutputStream(repertoireDst + "\\" + intitule + "_V2_BlobEcritDirectement.txt");
int b = 0;
while ((b = is.read()) != -1) {
fos1.write(b);
}
fos1.flush();
fos1.close();
/**************************************************************************
* Testing for base 64 encoding
************************************************************************/
File fichierDestinationTemp = new File(repertoireDst + "\\" + intitule + "_V3_FichierTxtTemp.txt");
File fichierDestinationTemp2 = new File(repertoireDst + "\\" + intitule + "_V4_FichierEncoderDecoder.txt");
File fichierDestinationTemp3 = new File(repertoireDst + "\\" + intitule + "_V5_FichierEncoder." + extension);
File fichierDestination = new File(repertoireDst + "\" + intitule + "." + extension);
PrintWriter writer = new PrintWriter(fichierDestinationTemp, "Cp1252");
writer.print(document2);
writer.close();
byte[] encodedBytes = Base64.getEncoder().encode(output);
String encodedString = new String(encodedBytes);
FileOutputStream fos2 = new FileOutputStream(fichierDestinationTemp3);
fos2.write(encodedString.getBytes());
fos2.flush();
fos2.close();
byte[] decodedBytes = Base64.getDecoder().decode(encodedString);
FileOutputStream fos3 = new FileOutputStream(fichierDestinationTemp2);
fos3.write(decodedBytes);
fos3.flush();
fos3.close();
Of course this creates my all sort of files, but non of the pdf files is readable. I guess I miss something. (And yeah I know that some parts I'm writing into .txt files but this was to see what I would get and hey, some of them where even in chinse...)
Any idea is welcome, wondering what I'm missing.
I finally found out what type of data was stored, the 0x78 is corresponding to zlib 4.0. This means I was able to inflate the data with an InflateOutputStream in java. Then I just had to save the data with a .pdf extension and everything was fine afterwards.
Related
I am trying to implement a function that un-tars a file. Below is the code I have written using JTar
private void untar(String tarFile, String destFolder) throws IOException {
TarInputStream tis = new TarInputStream(new BufferedInputStream(new FileInputStream(tarFile)));
TarEntry entry;
while (( entry = tis.getNextEntry() ) != null) {
System.out.println( "Extracting: " + entry.getName() );
int count;
byte data[] = new byte[2048];
if (entry.isDirectory()) {
new File( destFolder + "/" + entry.getName() ).mkdirs();
continue;
} else {
int di = entry.getName().lastIndexOf( '/' );
System.out.println("File"+di);
if (di != -1) {
File f = new File( destFolder + "/" + entry.getName().substring( 0, di ) );
if(f.mkdirs())
System.out.println(f.isDirectory());
}
}
FileOutputStream fos = new FileOutputStream( destFolder + "/" + entry.getName() );
BufferedOutputStream dest = new BufferedOutputStream( fos );
while (( count = tis.read( data ) ) != -1) {
dest.write( data, 0, count );
}
dest.flush();
dest.close();
}
tis.close();
}
When I hit the mkdirs() part and try to create a directory it does not do so, and I cannot see any output on console after the if statement.
Possibly this is the reason that the subsequent code for FileOutputStream shows an IOexception stating not a directory.
I can't find a solution for this problem anywhere.
Below is a program which saves the bytes to a .png file and zips into a given name folder.
byte[] decodedBytes = Base64.decodeBase64(contents);
// System.out.println(new String(decodedBytes));
InputStream targetStream = new ByteArrayInputStream(decodedBytes);
int count;
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFilePath));
out.putNextEntry(new ZipEntry(pngFile));
byte[] b = new byte[1024];
while ((count = targetStream.read(b)) > 0) {
out.write(b, 0, count);
}
out.flush();
out.close();
targetStream.close();
When i open it manually using 7 zip I see the following folder structure (c:\output\nameofzipfile.zip\nameofpng.png\nameofpng). Why is this happening? What am I doing wrong? As per my understanding this should be the structure (c:\output\nameofzipfile.zip\nameofpng.png)
Worked with the following code
byte[] decoded = Base64.decodeBase64(contents);
try (FileOutputStream fos = new FileOutputStream(zipFilePath + amazonOrderId + zipFileName)) {
fos.write(decoded);
fos.close();
}
file = new File(destDirectory + amazonOrderId + pngFile);
if (file.exists()) {
file.delete();
}
try (OutputStream out = new FileOutputStream(destDirectory + amazonOrderId + pngFile)) {
try (InputStream in = new GZIPInputStream(
new FileInputStream(zipFilePath + amazonOrderId + zipFileName))) {
byte[] buffer = new byte[65536];
int noRead;
while ((noRead = in.read(buffer)) != -1) {
out.write(buffer, 0, noRead);
}
}
}
I am downloading a PDF from a URL and saving it to my local drive.
The download code is working perfectly, the problem is that when I try to measure the size of the file it always claims it to be 52 bytes. I'm baffled... could you please review my code and tell me if I'am missing something?
try {
link = new URL("http://www.annualreports.co.uk/HostedData/AnnualReports/PDF/LSE_" + entry[0] + "_2015.pdf");
// http://www.annualreports.co.uk/HostedData/AnnualReports/PDF/LSE_BT_2015.pdf
InputStream in = new BufferedInputStream(link.openStream());
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int n = 0;
while (-1!=(n=in.read(buf)))
{
out.write(buf, 0, n);
}
out.close();
in.close();
byte[] response = out.toByteArray();
FileOutputStream fos = new FileOutputStream(fileName);
fos.write(response);
fos.close();
} catch (Exception e) {
System.out.println("Couldn't retrieve : " + entry[1] + " " + year);
}
int bytes = fileName.length();
System.out.println(bytes);
Here. Just simply try this.
URL url = new URL("http://www.annualreports.co.uk/HostedData/AnnualReports/PDF/LSE_" + entry[0] + "_2015.pdf");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.addRequestProperty("User-Agent", "Mozilla/4.76");
int size = conn.getContentLength();
if (size < 0) {
System.out.println("File not found");
} else {
System.out.println("File size in Bytes: " + size);
}
I have a code that creates xml.
public void createXML(InputStream in, String fileName) throws IOException {
baos = new ByteArrayOutputStream();
byte[] buf = new byte[BUF_SIZE];
int readNum = 0;
Writer writer = new BufferedWriter(new OutputStreamWriter(FileUtil.getOutputStream(fileName, FileUtil.HDD)));
writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
writer.write("\t<" + imageFileName + ">\r\n");
writer.write("\t\t");
try {
while ((readNum = in.read(buf)) >= 0) {
baos.write(buf, 0, readNum);
writer.write(baos.toString());
baos.reset();
}
}
finally {
if (in != null) {
in.close();
baos.close();
}
}
writer.write("\r\n\t<" + imageFileName + ">");
writer.close();
baos = null;
buf = null;
}
I want to create this xml into multiple parts (maximum of 500kb each). How can I do this? Is there any way for me to determine that the created file is already 500kb and write the remaining data to a different file?
I used this but the image after decoding the base64 string, the image produced is corrupted on the portion where it was cut.
for(int i = 1; i <= numberOfFiles; i++){
baos = new ByteArrayOutputStream();
String filePartName = fileName + ".part" + i + ".xml";
Writer writer = new BufferedWriter(new OutputStreamWriter(FileUtil.getOutputStream(filePartName, FileUtil.HDD)));
writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
writer.write("\t<" + filePartName + ">\r\n");
writer.write("\t\t");
int size = 0;
while ((readNum = in.read(buf)) >= 0 && size < 512000) {
baos.write(buf, 0, readNum);
size = size + readNum;
writer.write(baos.toString());
baos.reset();
}
writer.write("\r\n\t<" + filePartName + ">");
writer.close();
baos.close();
}
}
in.close();
If you keep a sum total of readNum that is in
while ((readNum = in.read(buf)) >= 0)
then you can test for its value and create new files when ever you want.
500kb = 512000 bytes. Use another ByteArrayOutputStream instanse to control this limit.
How to convert AppEngineFile to an array of bytes?
I have my File created from the blobkey like this
AppEngineFile file = fileService.getBlobFile(new BlobKey("blob key"));
I already tried something like this
FileService fileService = FileServiceFactory.getFileService();
// Create a new Blob file with mime-type "text/plain"
AppEngineFile file = fileService.getBlobFile(new BlobKey(video.getBlobkey()));
BlobstoreInputStream b = new BlobstoreInputStream(new BlobKey(video.getBlobkey()));
RandomAccessFile f = new RandomAccessFile(file.getFullPath(), "r");
byte[] pixels = b.read(); //doesn't work
The idea is to send this array of bytes with a POST request.
Here is my code i have to build the request:
String attachmentName = "test";
String attachmentFileName = "test.mp4";
String crlf = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
HttpURLConnection httpUrlConnection = null;
URL url = new URL("http://example.com/server.cgi");
httpUrlConnection = (HttpURLConnection) url.openConnection();
httpUrlConnection.setUseCaches(false);
httpUrlConnection.setDoOutput(true);
DataOutputStream request = new DataOutputStream(httpUrlConnection.getOutputStream());
request.writeBytes(twoHyphens + boundary + crlf);
request.writeBytes("Content-Disposition: form-data; name=\"" + attachmentName + "\";filename=\"" + attachmentFileName + "\"" + crlf);
request.writeBytes(crlf);
// Get a file service
FileService fileService = FileServiceFactory.getFileService();
// Create a new Blob file with mime-type "text/plain"
AppEngineFile file = fileService.getBlobFile(new BlobKey(video.getBlobkey()));
BlobstoreInputStream b = new BlobstoreInputStream(new BlobKey(video.getBlobkey()));
RandomAccessFile f = new RandomAccessFile(file.getFullPath(), "r");
byte[] pixels = b.read();
request.write(pixels);
request.writeBytes(crlf);
request.writeBytes(twoHyphens + boundary + twoHyphens + crlf);
request.flush();
request.close();
InputStream responseStream = new BufferedInputStream(httpUrlConnection.getInputStream());
BufferedReader responseStreamReader = new BufferedReader(new InputStreamReader(responseStream));
String line = "";
StringBuilder stringBuilder = new StringBuilder();
while ((line = responseStreamReader.readLine()) != null)
{
stringBuilder.append(line).append("\n");
}
responseStreamReader.close();
String response = stringBuilder.toString();
System.out.println(response);
You can simply do this:
FileReadChannel ch = fileservice.openReadChannel(file, true);
byte[] data = getBytes(Channels.newInputStream(ch));
and use this handy method (useable elsewhere):
public static byte[] getBytes(InputStream is) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int len;
byte[] data = new byte[100000]; // adapt buffer size to your needs
while ((len = is.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, len);
}
buffer.flush();
return buffer.toByteArray();
}
AppEngineFile file = ...
int size = (int) fileservice.stat(file).getLength().longValue();
FileReadChannel ch = fileservice.openReadChannel(file, true);
ByteBuffer dst = ByteBuffer.allocate(size);
try {
int sum=0;
while (sum<size) {
int read = ch.read(dst);
sum+=read;
}
} finally {ch.close();}
bytes byte[] = dst.array();
(This is NOT the way of reading from a Channel in Java, but it seems there is a bug in appengine that requires you know the exact count of bytes).