How to save the Picture content to Neo4J Database? About Java IO - java

I am a freshman in Neo4J. I think I am also a freshman in Java though I have learn it for neary 2 years.
I want to save and read a picture in neo4j database, I have a InputStream instance, Its cotent is a picture data. I have a Resoucre Object. it has a byte[] property used to save the picture data. so I do that
public static Resource getResourceInstance(InputStream in, String title) throws IOException{
StringBuilder sb = new StringBuilder();
BufferedInputStream input = new BufferedInputStream(in);
int b;
while((b = input.read()) != -1){
sb.append(b);
}
input.close();
in.close();
return new Resource(sb.toString().getBytes(), title, 0, 0);
}
then I use a transaction to save it to neo4j. and I check it by neo4j-server. in database, the byte array is number like 51,52,45 and so on
the second step I want to read the byte array from database.
I put it in Resource Object. and use FileOutputStream read it the code like this
images = resource.getImage();
String titleString = resource.getTitle();
String path = "images" + File.separator + titleString + ".jpg";
System.out.println(Paths.get(path).toRealPath());
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(new File(path)));
out.write(images);
out.close();
this is a Java web project.
I don't know why I have to create a file in path(String path = "images" + File.separator + titleString + ".jpg";) at first.
though I do so, I can't open the file like a picture.
I am very dispirited now. and I don't konw how to do. can you help me?
thank you very much.
PS:
my english is poor,bet your tolerating.

don't do this in the first place.
store the picture on a filesystem or a public storage like s3, dropbox etc. and save the url or filename in the neo4j property.
If you want to read a file into a byte[] create an array of the file.length() size and read into that array using the right offset until is. read() returns -1

Related

How read XLS file from gcp bucket

I have on bucket XLS file and I have to pull the file and read the data on the stream and work with data. I worked with CSV file and this is my code:
try (ReadChannel reader = storage.reader(bucketName, fileName)) {
ByteBuffer bytes = ByteBuffer.allocate(BUFFER_SIZE);
while (reader.read(bytes) > 0) {
bytes.flip();
// outChannel.write(bytes);
set(new String(bytes.array(), "UTF-8"), fileName);
bytes.clear();
}
}
I think this might be what you are looking for. GCS Input Channel
GcsService gcsService = GcsServiceFactory.createGcsService();
GcsFilename fileName = new GcsFilename("TestBucket", "Test1.xlsx");
GcsInputChannel readChannel = gcsService.openPrefetchingReadChannel(fileName, 0, BUFFER_SIZE);
InputStream inputStream = Channels.newInputStream(readChannel);
I've also found an interesting workaround that might help you, in this answer you have a piece of code that converts all the excel files to CSV to let you manipulate them as normal if you wish to.
EDIT: The error was there because it was not initialized. Have a look at my code edit.
In your case as far as I understood you might need to use "OutputChannel" not "InputChannel" but it's the same concept.
Hope this helps.

Issue with reading Tiff image metadata with imageIO

I'm writing a program that is supposed to taking in a bunch of tiff's and put them together. I got it to work for most of the image files I read in but a large batch of them throw out an error when I try to read them in.
Here is a snippet of code I have:
int numPages = 0;
inStream = ImageIO.createImageInputStream(imageFile);
reader.setInput(inStream);
while(true){
bufferedImages.add(reader.readAll(numPages, reader.getDefaultReadParam()));
numPages++;
}
Yes I catch the out of bounds exception so we don't have to worry about that. My problem is that I get the following error:
javax.imageio.IIOException: I/O error reading image metadata!
at com.sun.media.imageioimpl.plugins.tiff.TIFFImageReader.readMetadata(TIFFImageReader.java:340)
at com.sun.media.imageioimpl.plugins.tiff.TIFFImageReader.seekToImage(TIFFImageReader.java:310)
at com.sun.media.imageioimpl.plugins.tiff.TIFFImageReader.prepareRead(TIFFImageReader.java:971)
at com.sun.media.imageioimpl.plugins.tiff.TIFFImageReader.read(TIFFImageReader.java:1153)
at javax.imageio.ImageReader.readAll(ImageReader.java:1067)
at sel.image.appender.ImageAppender.mergeImages(ImageAppender.java:59)
at sel.imagenow.processor.AetnaLTCProcessor.processBatch(AetnaLTCProcessor.java:287)
at sel.imagenow.processor.AetnaLTCProcessor.processImpl(AetnaLTCProcessor.java:81)
at sel.processor.AbstractImageNowProcessor.process(AbstractImageNowProcessor.java:49)
at sel.RunConverter.main(RunConverter.java:37)
Caused by: java.io.EOFException
at javax.imageio.stream.ImageInputStreamImpl.readShort(ImageInputStreamImpl.java:229)
at javax.imageio.stream.ImageInputStreamImpl.readUnsignedShort(ImageInputStreamImpl.java:242)
at com.sun.media.imageioimpl.plugins.tiff.TIFFIFD.initialize(TIFFIFD.java:194)
at com.sun.media.imageioimpl.plugins.tiff.TIFFImageMetadata.initializeFromStream(TIFFImageMetadata.java:110)
at com.sun.media.imageioimpl.plugins.tiff.TIFFImageReader.readMetadata(TIFFImageReader.java:336)
... 9 more
I did make sure to add in the right JAI lib and my reader is using the "TIFF" type so the reader (and writer) is correct but for some reason the metadata is wrong. Now I can open and view all these images normally in windows so they really aren't corrupted or anything. Java just doesn't want to read them in right. Since I'm just using the stream meatadata to write them out later I don't care that much about the metadata I just need it to read in the file to the list so I can append it. I did find a writer.replaceImageMetaData method on the writer but the TIFFwriter version of IOWriter doens't have code for it. I'm stuck, anyone anything? Is there maybe a way to read in parts of the metadata to see what is wrong and fix it?
For anyone that would like to know I ended up fixing my own issue. It seems the the image metadata was a bit screwed up. Since I was just doing a plain merge and since I knew each image was one page I was able to use a buffered image to read in the picture then make it a IIOImage with null metadata. I used the stream metadata (which worked) to merge the images. Here is my complete method I use to merge a list of images:
public static File mergeImages(List<File> files, String argID, String fileType, String compressionType) throws Exception{
//find the temp location of the image
String location = ConfigManager.getInstance().getTempFileDirectory();
logger_.debug("image file type [" + fileType + "]");
ImageReader reader = ImageIO.getImageReadersByFormatName(fileType).next();
ImageWriter writer = ImageIO.getImageWritersByFormatName(fileType).next();
//set up the new image name
String filePath = location + "\\" + argID +"." + fileType;
//keeps track of the images we copied from
StringBuilder builder = new StringBuilder();
List<IIOImage> bufferedImages = new ArrayList<IIOImage>();
IIOMetadata metaData = null;
for (File imageFile:files) {
//get the name for logging later
builder.append(imageFile.getCanonicalPath()).append("\n");
if (metaData == null){
reader.setInput(ImageIO.createImageInputStream(imageFile));
metaData = reader.getStreamMetadata();
}
BufferedImage image = ImageIO.read(imageFile);
bufferedImages.add(new IIOImage(image, null, null));
}
ImageWriteParam params = writer.getDefaultWriteParam();
if (compressionType != null){
params.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
params.setCompressionType(compressionType);
}
ImageOutputStream outStream = null;
try{
outStream = ImageIO.createImageOutputStream(new File(filePath));
int numPages = 0;
writer.setOutput(outStream);
for(IIOImage image:bufferedImages){
if (numPages == 0){
writer.write(metaData, image, params);
}
else{
writer.writeInsert(numPages, image, params);
}
numPages++;
}
}
finally{
if (outStream != null){
outStream.close();
}
}
//set up the file for us to use later
File mergedFile = new File(filePath);
logger_.info("Merged image into [" + filePath + "]");
logger_.debug("Merged images [\n" + builder.toString() + "] into --> " + filePath);
return mergedFile;
}
I hope this help someone else because I know there isn't much on this issue that I could find.

How do I make my program find the record store?

I've just started out with J2ME and record stores. This seems to be the proper way to open a record store named "foo", not creating a new one:
RecordStore.openRecordStore("foo", false)
Fine, I get that. But where do I put the actual file for my program to find it? I'm using NetBeans 7.1.2.
you don't need to know where the file is, J2Me put the file somewhere, if the store already exists, you can open it, or use true in the open method to create it if it doesn't exist.
RecordStore rs = RecordStore.openRecordStore("foo", true);
to write to your recordstore, use this :
String s = "your-data";
byte[] rec = s.getBytes();
rs.addRecord(rec, 0, rec.length);
to read :
RecordEnumeration re = rs.enumerateRecords(null, null, false);
while (re.hasNextElement()){
String s = new String(re.nextRecord());
}
and close your recordStore after each operation:
rs.closeRecordStore();
update
how do I read the contents of the file?
read your existing file as a normal file with :
InputStream is = getClass().getResourceAsStream("/res/foo");
StringBuffer sb = new StringBuffer();
int chars;
while ((chars = is.read()) != -1)
sb.append((char) chars);
String str = new String(String.valueOf(sb).getBytes("UTF-8"));
and write the string to your recordStore with the code above.

Convert byte array into a file without writing the file to a disk

I have saved icon size images in a mysql database in bytes, now, what I need to do is retrieve those file bytes from the database and show those images in a swing application, I have a method which gets the bytes from the database and convert it back to a file but I have to write that file in to the disk
this is my method,
public void downloadFile(int FamerId) throws Exception {
String sql = "SELECT * FROM images WHERE famer_id=?";
Connection con = JDBCConnectionPool.getInstance().checkOut();
PreparedStatement ps = con.prepareStatement(sql);
ps.setInt(1, FamerId);
ResultSet resultSet = ps.executeQuery();
int count = 0;
while (resultSet.next()) {
ByteArrayInputStream bais;
ObjectInputStream inputStream;
bais = new ByteArrayInputStream(resultSet.getBytes("image"));
inputStream = new ObjectInputStream(bais);
SaveFile sf = (SaveFile) inputStream.readObject();
FileOutputStream out = new FileOutputStream("fileLocation/" + resultSet.getString("image_name"));
byte[] bytes = sf.getArray();
int c = 0;
while (c < bytes.length) {
out.write(bytes[c]);
c++;
}
out.close();
inputStream.close();
bais.close();
JDBCConnectionPool.getInstance().checkOut();
}
}
but this method doesn't give what I need, please assist me.
You can read images directly from byte streams with the ImageIO class. Assuming of course that you have previously written the image data in a compatible format. Which is hard to say given the fact that in your code you use an intermediary object input stream when reading your byte data. Here's an example of how you can create an image directly from the database without using intermediary files:
bais = new ByteArrayInputStream(resultSet.getBytes("image"));
final BufferedImage image = ImageIO.read(bais);
// pass the image to your Swing layer to be rendered.
And an example of how you would have written the data to the database, in order to be able to use this code:
final ByteArrayOutputStream baos = new ByteArrayOutputStream(64000);
ImageIO.write(image, "PNG", baos);
final byte[] data = baos.toByteArray();
// write data to database
The answer to your question is its platform dependent. From the docs
A file output stream is an output stream for writing data to a File or
to a FileDescriptor. Whether or not a file is available or may be
created depends upon the underlying platform. Some platforms, in
particular, allow a file to be opened for writing by only one
FileOutputStream (or other file-writing object) at a time. In such
situations the constructors in this class will fail if the file
involved is already open.
FileOutputStream is meant for writing streams of raw bytes such as
image data. For writing streams of characters, consider using
FileWriter.
So if you want to write to a file then file may or may not be created.
If you don't want to create the file and you are just interested in byte[] (content of the file) you can then use solution provided by #Perception or can just pass the inputStream that you have already created.

Get filename from an inputstream (Java)

if I have this code, how could I keep the filename of the original file or reassign it to the new one?:
InputStream input= assetInfo.openStream();
File t = new File("");
OutputStream out = new FileOutputStream(t);
int read=0;
byte[] bytes = new byte[1024];
while((read = input.read(bytes))!= -1){
out.write(bytes, 0, read);
}
An input stream can be created to read from a file or from any other source of data. Therefore it makes no sense to have a filename attached to an input stream. Look in assetInfo to see if that class exposes that data (you can even look inside the class using reflection). Note that the creator or assetInfo made a design mistake not exposing this information, OR you are trying to make one now.

Categories