如何读取包含文本和图像数据的文件?

时间:2013-12-06 01:54:12

标签: java image file text bufferedreader

我有一个具有以下结构的文件:

<number>
<title>
<text>
<image data>

例如:

176
Elephant
This image shows a cute elephant.
<image data bytes go here>

我像这样写上面的例子:

String filepath = "myfile.txt";
BufferedImage image = ...; //load some image here

try(FileOutputStream output = new FileOutputStream(filepath);
BufferedWriter writer = new BufferedWriter(new FileWriter(filepath)))
{
    writer.write("Number: 176");
    writer.newLine();
    writer.write("Title: Elephant");
    writer.newLine();
    writer.write("Text: This image shows a cute elephant.");
    writer.newLine();

    ImageIO.write(image, "png", output);

    writer.flush();
}
catch (Exception) {//exception handling}

这很好用。但是,我不知道如何阅读该文件。 问题是我需要调用ImageIO.read()来解析图像,但我不能用BufferedReader调用它。我的草稿看起来像这样:

String filepath = "myfile.txt";

try (BufferedReader reader = new BufferedReader(new java.io.FileReader(filepath)))
{
    String number = reader.readLine();
    reader.readLine(); //skip a free line

    String title = reader.readLine();
    reader.readLine(); //skip a free line

    String text = reader.readLine();
    reader.readLine(); //skip a free line

    BufferedImage image = ???; //how can I read the image here? <----------------

}
catch (Exception e) {//error handling ...}

所以:我如何阅读图像(使用ImageIO)?

非常感谢任何帮助:)


编辑:就像我用两个不同的作家写作一样,是否有可能在阅读时使用两个读者?就像“读取3行字符串,然后读取一行二进制数据”。

4 个答案:

答案 0 :(得分:2)

正如我所看到的,问题在于读者和流的混合......

现在,我尝试使用...

try (OutputStream output = new FileOutputStream(filepath);
                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output))) {

    writer.write("Number: 176");
    writer.newLine();
    writer.write("Title: Elephant");
    writer.newLine();
    writer.write("Text: This image shows a cute elephant.");
    writer.newLine();

    writer.flush();

    ImageIO.write(image, "png", output);

    output.flush();
} catch (Exception exp) {
    exp.printStackTrace();
}

编写文件。希望输入流位置将被更新,内容将被写入文件的末尾......

String filepath = "myfile.txt";
BufferedImage image = null;
try (InputStream is = new FileInputStream(new File(filepath));
                BufferedReader br = new BufferedReader(new InputStreamReader(is))) {

    String number = br.readLine();
    String title = br.readLine();
    String text = br.readLine();

    System.out.println(number);
    System.out.println(title);
    System.out.println(text);

    ImageInputStream iis = ImageIO.createImageInputStream(is);
    image = ImageIO.read(iis);
    ImageIO.write(image, "png", new File("test.png"));
} catch (Exception exp) {
    exp.printStackTrace();
}

阅读。

但这似乎不起作用。 “可能”发生的是文件位置没有更新到我们需要它正确读取图像的正确位置。

我所做的却是......

import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageInputStream;

public class ReadWriteImage {

    public static void main(String[] args) {
        try {
            writeTest();
            readTest();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public static void readTest() throws IOException {
        String filepath = "myfile.txt";
        BufferedImage image = null;
        try (InputStream is = new FileInputStream(new File(filepath))) {

            int lineCount = 0;
            StringBuilder sb = new StringBuilder(128);

            String number = null;
            String title = null;
            String text = null;

            int b = -1;
            while (lineCount < 3 && (b = is.read()) != -1) {
                if ((char)b == '\n') {
                    switch (lineCount) {
                        case 0:
                            number = sb.toString();
                            break;
                        case 1:
                            title = sb.toString();
                            break;
                        case 2:
                            text = sb.toString();
                            break;
                    }
                    sb.delete(0, sb.length());
                    lineCount++;
                } else {
                    sb.append((char)b);
                }
            }

            System.out.println(number);
            System.out.println(title);
            System.out.println(text);

            ImageInputStream iis = ImageIO.createImageInputStream(is);
            image = ImageIO.read(iis);
            ImageIO.write(image, "png", new File("test.png"));
        } catch (Exception exp) {
            exp.printStackTrace();
        }
    }

    public static void writeTest() throws IOException {
        String filepath = "myfile.txt";
        BufferedImage image = ImageIO.read(new File("/Users/swhitehead/Dropbox/MegaTokyo/thumnails/2005-09-29-3957_400.jpg"));

        try (FileOutputStream output = new FileOutputStream(filepath)) {

            output.write("Number: 176\n".getBytes());
            output.write("Title: Elephant\n".getBytes());
            output.write("Text: This image shows a cute elephant.\n".getBytes());

            ImageIO.write(image, "png", output);

            output.flush();
        } catch (Exception exp) {
            exp.printStackTrace();
        }

    }
}

基本上,我直接使用了OutputStreamInputStream ...

<强>更新

文件内容以...开头

Number: 176
Title: Elephant
Text: This image shows a cute elephant.
âPNG

答案 1 :(得分:0)

你不能按照自己的方式写图像。您需要将IMAGE转换为BYTES数组,然后将BYTES数组转换为BASE64。这意味着您需要将IMAGE转换为Base64字符串,然后将SAVE base64字符串转换为该文件。读取文件时,需要将Base64 String转换回BYTES数组,然后将BYTES数组转换为图像。

此链接可以帮助您:'http://ben-bai.blogspot.com/2012/08/java-convert-image-to-base64-string-and.html'

答案 2 :(得分:0)

给出你的例子的方法:

这很简单,如果您的示例中只列出了3行文字,那么当您检测到Text时,您可以只读取\n的每一行,当您到达第三行时你知道图像数据是下一个,然后只是从你的图像中读取偏移量。

更好的方法是首先使用binary数据的偏移量编写一个简单的索引标题,然后您不必解析您可以阅读的\n直至偏移并将所有内容视为文本,然后从偏移量中读取并将其余部分视为您的图像。

没有理由需要对Base64或类似的东西进行任何编码,这会使文件格式膨胀并导致更复杂的问题。

答案 3 :(得分:0)

不确定它是否可行,但正如@MadProgrammer所说,使用ImageIO.read调用中BufferedReader初始化的同一个阅读器:

Reader fileReader = new FileReader(...);
BufferedReader reader = new BufferedReader(fileReader);
...
BufferedImage img = ImageIO.read(fileReader);

或者,使用FileReader(FileInputStream)...毕竟,在写作时你正在做一些非常相似的事情。这里要学习的教训:对称总是有助于这样的情况。