C++ ofstream写文件时OD错误 ifstream读文件时0x20错误

本文探讨了在C++中使用ofstream写入特定十六进制值时遇到的问题,特别是当值包含0A时,输出结果会被自动转换为0D0A的现象。文章解释了这一现象的原因,并给出了通过设置文件打开模式为二进制来解决该问题的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前一阵子用C++写东西,需要往文件里写数据,很简单的代码,大概是这个样子:

#include <fstream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
 ofstream fout;
 fout.open("d://test.dat");

 int a = 0x7788;

 fout.write((char*) &a, sizeof(int));
}

打开test.dat,内容是77 88 00 00,很正常。
打开test.dat,内容是77 88 00 00,很正常。

但我要是把a的值改成0x0a,毛病就出来了,写出来的东西是:0D 0A 00 00 00!

要是把a改成0x770a或者是别的什么0a,只要是数字中某一个字节是0a,写出来以后肯定变成0D 0A!比如0x770a就变成0D 0A 77!

更让人寒的是,即使规定写出的只能是一个字节,即写:
fout.write((char*) &a, sizeof(char));
只要a的值的高字节是0a,写出来一样变成0D 0A!也就是指定输出1个字节,实际却输出了2个字节!

真是让人费解啊。我一度认为C++出现了有史以来最莫名其妙的BUG,不过,且慢……

0A是什么?0D 0A又是什么?这个问题的解原来在这里。先查查C++的文档,里面说明,ofstream的open函数,第二个参数指明打开方式,缺省为ios_base::out,即按照字节流的方式输出文本。再看看0A到底是什么,原来ASCII的0A是换行,也就是/n,再想想,Windows系统下的换行是如何处理的?/r/n啊。原来……

原来按照字节流的形式输出文本时,ofstream会自动将输出的/n变成/r/n,以适应WIndows系统,结果以输出数据的角度看来,这个正常的举动就变成了不可解的“0A变成0D 0A”。

既然如此,答案也出来了,查查文档,将打开文件的一句改成:
fout.open(“d://test.dat”, ios_base::out | ios_base::binary);
捣乱的0A终于归位了。


ifstream读取文件时,如果使用in>>ch方法,则ifstream会自动将空格去除,故0x20不会读取,同样加入读取参数ios::binary后,问题解决。

现有5个java类,请将这些java类转化为对应功能的c++类 1.package careray.structure.header; import java.util.LinkedHashMap; import careray.structure.Constants; import careray.utils.Tools; public class SeqFileHeader extends Header { private static final String TYPE_CODE_SEQ = "SEQ"; public static final int FILE_HEADER_LENGTH = 1024; private short[] data; private static LinkedHashMap<String, Integer> IMAGE_PROPERTIES = new LinkedHashMap<String, Integer>(); static { IMAGE_PROPERTIES.put("typeCode", 8); IMAGE_PROPERTIES.put("fileHeaderSize", 4); IMAGE_PROPERTIES.put("fileSize", 4); IMAGE_PROPERTIES.put("imgWidth", 4); IMAGE_PROPERTIES.put("imgHeight", 4); IMAGE_PROPERTIES.put("bitDepth", 4); IMAGE_PROPERTIES.put("storageType", 4); IMAGE_PROPERTIES.put("endianType", 4); IMAGE_PROPERTIES.put("compressType", 4); IMAGE_PROPERTIES.put("startTime", 24); IMAGE_PROPERTIES.put("endTime", 24); IMAGE_PROPERTIES.put("frameNum", 4); IMAGE_PROPERTIES.put("frameRate", 4); IMAGE_PROPERTIES.put("frameHeaderSize", 4); } private String typeCode = TYPE_CODE_SEQ; private int fileHeaderSize = FILE_HEADER_LENGTH; private int fileSize; private int imgWidth; private int imgHeight; private int bitDepth = 16; private int storageType = 16; private int endianType = Constants.ENDIAN_INTEL; private int compressType = 0; private String startTime; private String endTime; private int frameNum; private float frameRate; private int frameHeaderSize = FrameHeader.FRAME_HEADER_LENGTH; private static LinkedHashMap<String, Integer> DETECTOR_PROPERTIES = new LinkedHashMap<String, Integer>(); static { DETECTOR_PROPERTIES.put("machineID", 16); DETECTOR_PROPERTIES.put("hwVersion", 32); DETECTOR_PROPERTIES.put("fmVersion", 32); DETECTOR_PROPERTIES.put("modeID", 4); DETECTOR_PROPERTIES.put("triggerMode", 4); DETECTOR_PROPERTIES.put("exposeWin", 4); } public String toString() { StringBuilder sb = new StringBuilder(); sb.append("typeCode: ").append(typeCode).append(Constants.NEW_LINE).append("fileHeaderSize: ") .append(fileHeaderSize).append(Constants.NEW_LINE).append("fileSize: ").append(fileSize) .append(Constants.NEW_LINE).append("imgWidth: ").append(imgWidth).append(Constants.NEW_LINE) .append("imgHeight: ").append(imgHeight).append(Constants.NEW_LINE).append("bitDepth: ") .append(bitDepth).append(Constants.NEW_LINE).append("storageType: ").append(storageType) .append(Constants.NEW_LINE).append("startTime: ").append(startTime).append(Constants.NEW_LINE) .append("endTime: ").append(endTime).append(Constants.NEW_LINE).append("frameNum: ").append(frameNum) .append(Constants.NEW_LINE).append("frameRate: ").append(frameRate).append(Constants.NEW_LINE) .append("frameHeaderSize: ").append(frameHeaderSize).append(Constants.NEW_LINE); return sb.toString(); } private String machineID; private String hwVersion; private String fmVersion; private int modeID; private int triggerMode; private int exposeWin; private static LinkedHashMap<String, Integer> API_PROPERTIES = new LinkedHashMap<String, Integer>(); static { API_PROPERTIES.put("swVersion", 8); API_PROPERTIES.put("GWS_IP", 16); API_PROPERTIES.put("offsetCorrected", 4); API_PROPERTIES.put("gainCorrected", 4); API_PROPERTIES.put("defectCorrected", 4); API_PROPERTIES.put("denoised", 4); API_PROPERTIES.put("DGC", 4); API_PROPERTIES.put("resized", 4); API_PROPERTIES.put("LUT", 4); API_PROPERTIES.put("description", 128); } private String swVersion = "SDK5.1.0"; private String GWS_IP = "127.0.0.1"; private int offsetCorrected = 0; private int gainCorrected = 0; private int defectCorrected = 0; private int denoised = 0; private int DGC = 0; private int resized = 0; private int LUT = 0; private String description; private short[] generateHeaderData() { short[] headerData = new short[FILE_HEADER_LENGTH]; int offset = 0; int elementSize = IMAGE_PROPERTIES.get("typeCode") / Constants.BYTES_PER_SHORT; System.arraycopy(getShortData(Tools.getFixLengthStr(typeCode, IMAGE_PROPERTIES.get("typeCode")).getBytes()), 0, headerData, offset, elementSize); offset += elementSize; elementSize = IMAGE_PROPERTIES.get("fileHeaderSize") / Constants.BYTES_PER_SHORT; System.arraycopy(getShortData(fileHeaderSize), 0, headerData, offset, elementSize); offset += elementSize; elementSize = IMAGE_PROPERTIES.get("fileSize") / Constants.BYTES_PER_SHORT; System.arraycopy(getShortData(fileSize), 0, headerData, offset, elementSize); offset += elementSize; elementSize = IMAGE_PROPERTIES.get("imgWidth") / Constants.BYTES_PER_SHORT; System.arraycopy(getShortData(imgWidth), 0, headerData, offset, elementSize); offset += elementSize; elementSize = IMAGE_PROPERTIES.get("imgHeight") / Constants.BYTES_PER_SHORT; System.arraycopy(getShortData(imgHeight), 0, headerData, offset, elementSize); offset += elementSize; elementSize = IMAGE_PROPERTIES.get("bitDepth") / Constants.BYTES_PER_SHORT; System.arraycopy(getShortData(bitDepth), 0, headerData, offset, elementSize); offset += elementSize; elementSize = IMAGE_PROPERTIES.get("storageType") / Constants.BYTES_PER_SHORT; System.arraycopy(getShortData(storageType), 0, headerData, offset, elementSize); offset += elementSize; elementSize = IMAGE_PROPERTIES.get("endianType") / Constants.BYTES_PER_SHORT; System.arraycopy(getShortData(endianType), 0, headerData, offset, elementSize); offset += elementSize; elementSize = IMAGE_PROPERTIES.get("compressType") / Constants.BYTES_PER_SHORT; System.arraycopy(getShortData(compressType), 0, headerData, offset, elementSize); offset += elementSize; elementSize = IMAGE_PROPERTIES.get("startTime") / Constants.BYTES_PER_SHORT; System.arraycopy(getShortData(Tools.getFixLengthStr(startTime, IMAGE_PROPERTIES.get("startTime")).getBytes()), 0, headerData, offset, elementSize); offset += elementSize; elementSize = IMAGE_PROPERTIES.get("endTime") / Constants.BYTES_PER_SHORT; System.arraycopy(getShortData(Tools.getFixLengthStr(endTime, IMAGE_PROPERTIES.get("endTime")).getBytes()), 0, headerData, offset, elementSize); offset += elementSize; elementSize = IMAGE_PROPERTIES.get("frameNum") / Constants.BYTES_PER_SHORT; System.arraycopy(getShortData(frameNum), 0, headerData, offset, elementSize); offset += elementSize; elementSize = IMAGE_PROPERTIES.get("frameRate") / Constants.BYTES_PER_SHORT; System.arraycopy(getShortData(frameRate), 0, headerData, offset, elementSize); offset += elementSize; elementSize = IMAGE_PROPERTIES.get("frameHeaderSize") / Constants.BYTES_PER_SHORT; System.arraycopy(getShortData(frameHeaderSize), 0, headerData, offset, elementSize); return headerData; } public short[] getData() { if (data == null) { data = generateHeaderData(); } return data; } public void parse() { if (data == null) return; int offset = 0; typeCode = getString(data, offset, IMAGE_PROPERTIES.get("typeCode")).trim(); offset += IMAGE_PROPERTIES.get("typeCode") / Constants.BYTES_PER_SHORT; fileHeaderSize = getU32ByLE(data, offset); offset += IMAGE_PROPERTIES.get("fileHeaderSize") / Constants.BYTES_PER_SHORT; fileSize = getU32ByLE(data, offset); offset += IMAGE_PROPERTIES.get("fileSize") / Constants.BYTES_PER_SHORT; imgWidth = getU32ByLE(data, offset); offset += IMAGE_PROPERTIES.get("imgWidth") / Constants.BYTES_PER_SHORT; imgHeight = getU32ByLE(data, offset); offset += IMAGE_PROPERTIES.get("imgHeight") / Constants.BYTES_PER_SHORT; bitDepth = getU32ByLE(data, offset); offset += IMAGE_PROPERTIES.get("bitDepth") / Constants.BYTES_PER_SHORT; storageType = getU32ByLE(data, offset); offset += IMAGE_PROPERTIES.get("storageType") / Constants.BYTES_PER_SHORT; endianType = getU32ByLE(data, offset); offset += IMAGE_PROPERTIES.get("endianType") / Constants.BYTES_PER_SHORT; compressType = getU32ByLE(data, offset); offset += IMAGE_PROPERTIES.get("compressType") / Constants.BYTES_PER_SHORT; startTime = getString(data, offset, IMAGE_PROPERTIES.get("startTime")).trim(); offset += IMAGE_PROPERTIES.get("startTime") / Constants.BYTES_PER_SHORT; endTime = getString(data, offset, IMAGE_PROPERTIES.get("endTime")).trim(); offset += IMAGE_PROPERTIES.get("endTime") / Constants.BYTES_PER_SHORT; frameNum = getU32ByLE(data, offset); offset += IMAGE_PROPERTIES.get("frameNum") / Constants.BYTES_PER_SHORT; frameRate = getFloatByLE(data, offset); offset += IMAGE_PROPERTIES.get("frameRate") / Constants.BYTES_PER_SHORT; frameHeaderSize = getU32ByLE(data, offset); } public void setData(short[] data) { this.data = data; } public String getTypeCode() { return typeCode; } public void setTypeCode(String typeCode) { this.typeCode = typeCode; } public int getFileHeaderSize() { return fileHeaderSize; } public void setFileHeaderSize(int fileHeaderSize) { this.fileHeaderSize = fileHeaderSize; } public int getFileSize() { return fileSize; } public void setFileSize(int fileSize) { this.fileSize = fileSize; } public int getImgWidth() { return imgWidth; } public void setImgWidth(int imgWidth) { this.imgWidth = imgWidth; } public int getImgHeight() { return imgHeight; } public void setImgHeight(int imgHeight) { this.imgHeight = imgHeight; } public int getBitDepth() { return bitDepth; } public void setBitDepth(int bitDeepth) { this.bitDepth = bitDeepth; } public int getStorageType() { return storageType; } public void setStorageType(int storageType) { this.storageType = storageType; } public int getEndianType() { return endianType; } public void setEndianType(int endianType) { this.endianType = endianType; } public int getCompressType() { return compressType; } public void setCompressType(int compressType) { this.compressType = compressType; } public String getStartTime() { return startTime; } public void setStartTime(String startTime) { this.startTime = startTime; } public String getEndTime() { return endTime; } public void setEndTime(String endTime) { this.endTime = endTime; } public int getFrameNum() { return frameNum; } public void setFrameNum(int frameNum) { this.frameNum = frameNum; } public float getFrameRate() { return frameRate; } public void setFrameRate(float frameRate) { this.frameRate = frameRate; } public int getFrameHeaderSize() { return frameHeaderSize; } public void setFrameHeaderSize(int frameHeaderSize) { this.frameHeaderSize = frameHeaderSize; } public String getMachineID() { return machineID; } public void setMachineID(String machineID) { this.machineID = machineID; } public String getHwVersion() { return hwVersion; } public void setHwVersion(String hwVersion) { this.hwVersion = hwVersion; } public String getFmVersion() { return fmVersion; } public void setFmVersion(String fmVersion) { this.fmVersion = fmVersion; } public int getModeID() { return modeID; } public void setModeID(int modeID) { this.modeID = modeID; } public int getTriggerMode() { return triggerMode; } public void setTriggerMode(int triggerMode) { this.triggerMode = triggerMode; } public int getExposeWin() { return exposeWin; } public void setExposeWin(int exposeWin) { this.exposeWin = exposeWin; } public String getSwVersion() { return swVersion; } public void setSwVersion(String swVersion) { this.swVersion = swVersion; } public String getGWS_IP() { return GWS_IP; } public void setGWS_IP(String gWS_IP) { GWS_IP = gWS_IP; } public int getOffsetCorrected() { return offsetCorrected; } public void setOffsetCorrected(int offsetCorrected) { this.offsetCorrected = offsetCorrected; } public int getGainCorrected() { return gainCorrected; } public void setGainCorrected(int gainCorrected) { this.gainCorrected = gainCorrected; } public int getDefectCorrected() { return defectCorrected; } public void setDefectCorrected(int defectCorrected) { this.defectCorrected = defectCorrected; } public int getDenoised() { return denoised; } public void setDenoised(int denoised) { this.denoised = denoised; } public int getDGC() { return DGC; } public void setDGC(int dGC) { DGC = dGC; } public int getResized() { return resized; } public void setResized(int resized) { this.resized = resized; } public int getLUT() { return LUT; } public void setLUT(int lUT) { LUT = lUT; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } } 2.package careray.structure.header; import java.util.LinkedHashMap; import careray.structure.Constants; public class FrameHeader extends Header { public static int FRAME_HEADER_LENGTH = 256; public static final int HEADER_RESERVED_LENGTH = 6; public static final int DETECTOR_RESERVED_LENGTH = 126; public static final int SERVER_RESERVED_LENGTH = 75; /** * Map th save the names and sizes of the properties in header */ private static LinkedHashMap<String, Integer> PROPERTIES = new LinkedHashMap<String, Integer>(); static { PROPERTIES.put("length", 2); PROPERTIES.put("frameID", 4); PROPERTIES.put("relativeAcqTime", 4); PROPERTIES.put("absAcqTime", 8); PROPERTIES.put("blockLen", 4); PROPERTIES.put("avgTemp", 4); PROPERTIES.put("maxTemp", 4); PROPERTIES.put("vcmp", 4); PROPERTIES.put("vbias", 4); PROPERTIES.put("gain", 1); PROPERTIES.put("modeID", 1); PROPERTIES.put("detectorIndex", 1); PROPERTIES.put("qualityType", 1); PROPERTIES.put("offsetFlag", 1); PROPERTIES.put("gainFlag", 1); PROPERTIES.put("defectFlag", 1); PROPERTIES.put("crc", 4); } private short[] data = new short[FRAME_HEADER_LENGTH / Constants.BYTES_PER_SHORT]; private static int length = 256; private boolean spotFilm; private int frameID; private long absAcqTime; private int relativeAcqTime; private int blockLen; private float avgTemp; private float maxTemp; private float vcmp; private float vbias; private int gain; private int modeID; private int detectorIndex; private int qualityType; private int offsetFlag; private int gainFlag; private int defectFlag; private int crc; public void parse(short[] data) { System.arraycopy(data, 0, this.data, 0, data.length); parse(); } public void parse() { int offset = 0; length = data[offset]; spotFilm = 1 == (data[PROPERTIES.get("length") / Constants.BYTES_PER_SHORT] & 0xff); offset += (HEADER_RESERVED_LENGTH + PROPERTIES.get("length")) / Constants.BYTES_PER_SHORT; frameID = getU32ByLE(data, offset); offset += PROPERTIES.get("frameID") / Constants.BYTES_PER_SHORT; relativeAcqTime = getU32ByLE(data, offset) & 0xffffff; offset += PROPERTIES.get("relativeAcqTime") / Constants.BYTES_PER_SHORT; absAcqTime = getLong(data, offset) & 0xffffffff; offset += PROPERTIES.get("absAcqTime") / Constants.BYTES_PER_SHORT; blockLen = getU32ByLE(data, offset); offset += PROPERTIES.get("blockLen") / Constants.BYTES_PER_SHORT; avgTemp = getFloatByLE(data, offset); offset += PROPERTIES.get("avgTemp") / Constants.BYTES_PER_SHORT; maxTemp = getFloatByLE(data, offset); offset += PROPERTIES.get("maxTemp") / Constants.BYTES_PER_SHORT; vcmp = getFloatByLE(data, offset); offset += PROPERTIES.get("vcmp") / Constants.BYTES_PER_SHORT; vbias = getFloatByLE(data, offset); offset += PROPERTIES.get("vbias") / Constants.BYTES_PER_SHORT; short temp = data[offset]; gain = temp & 0x00ff; modeID = (temp >> 8) & 0x00ff; offset += 1; offset += DETECTOR_RESERVED_LENGTH / Constants.BYTES_PER_SHORT; temp = data[offset]; detectorIndex = temp & 0x00ff; qualityType = (temp >> 8) & 0x00ff; offset += 1; temp = data[offset]; offsetFlag = temp & 0x00ff; gainFlag = (temp >> 8) & 0x00ff; offset += 1; temp = data[offset]; defectFlag = temp & 0x00ff; offset += (SERVER_RESERVED_LENGTH - 1) / Constants.BYTES_PER_SHORT; crc = getU32ByLE(data, offset); } public String toString() { StringBuilder sb = new StringBuilder(); sb.append("length: ").append(length).append(Constants.NEW_LINE).append("spotFilm: ").append(spotFilm) .append(Constants.NEW_LINE).append("frameID: ").append(frameID).append(Constants.NEW_LINE) .append("absAcqTime: ").append(absAcqTime).append(Constants.NEW_LINE).append("relativeAcqTime: ") .append(relativeAcqTime).append(Constants.NEW_LINE).append("blockLen: ").append(blockLen) .append(Constants.NEW_LINE).append("avgTemp: ").append(avgTemp).append(Constants.NEW_LINE) .append("maxTemp: ").append(maxTemp).append(Constants.NEW_LINE).append("vcmp: ").append(vcmp) .append(Constants.NEW_LINE).append("vbias: ").append(vbias).append(Constants.NEW_LINE).append("gain: ") .append(gain).append(Constants.NEW_LINE).append("modeID: ").append(modeID).append(Constants.NEW_LINE) .append("detectorIndex: ").append(detectorIndex).append(Constants.NEW_LINE).append("qualityType: ") .append(qualityType).append(Constants.NEW_LINE).append("offsetFlag: ").append(offsetFlag) .append(Constants.NEW_LINE).append("gainFlag: ").append(gainFlag).append(Constants.NEW_LINE) .append("defectFlag: ").append(defectFlag).append(Constants.NEW_LINE).append("crc: ").append(crc) .append(Constants.NEW_LINE); return sb.toString(); } public short[] getData() { return data; } public void setData(short[] data) { this.data = data; } public int getFrameID() { return frameID; } public void setFrameID(int frameID) { this.frameID = frameID; } public int getGain() { return gain; } public void setGain(int gain) { this.gain = gain; } public int getModeID() { return modeID; } public void setModeID(int modeID) { this.modeID = modeID; } public static LinkedHashMap<String, Integer> getPROPERTIES() { return PROPERTIES; } public static void setPROPERTIES(LinkedHashMap<String, Integer> pROPERTIES) { PROPERTIES = pROPERTIES; } public long getAbsAcqTime() { return absAcqTime; } public void setAbsAcqTime(long absAcqTime) { this.absAcqTime = absAcqTime; } public int getRelativeAcqTime() { return relativeAcqTime; } public void setRelativeAcqTime(int relativeAcqTime) { this.relativeAcqTime = relativeAcqTime; } public int getBlockLen() { return blockLen; } public void setBlockLen(int blockLen) { this.blockLen = blockLen; } public float getAvgTemp() { return avgTemp; } public void setAvgTemp(float avgTemp) { this.avgTemp = avgTemp; } public float getMaxTemp() { return maxTemp; } public void setMaxTemp(float maxTemp) { this.maxTemp = maxTemp; } public float getVcmp() { return vcmp; } public void setVcmp(float vcmp) { this.vcmp = vcmp; } public float getVbias() { return vbias; } public void setVbias(float vbias) { this.vbias = vbias; } public int getDetectorIndex() { return detectorIndex; } public void setDetectorIndex(int detectorIndex) { this.detectorIndex = detectorIndex; } public int getQualityType() { return qualityType; } public void setQualityType(int qualityType) { this.qualityType = qualityType; } public int getOffsetFlag() { return offsetFlag; } public void setOffsetFlag(int offsetFlag) { this.offsetFlag = offsetFlag; } public int getGainFlag() { return gainFlag; } public void setGainFlag(int gainFlag) { this.gainFlag = gainFlag; } public int getDefectFlag() { return defectFlag; } public void setDefectFlag(int defectFlag) { this.defectFlag = defectFlag; } public int getCrc() { return crc; } public void setCrc(int crc) { this.crc = crc; } public static int getFrameHeaderLength() { return FRAME_HEADER_LENGTH; } public static int getHeaderReservedLength() { return HEADER_RESERVED_LENGTH; } public static int getDetectorReservedLength() { return DETECTOR_RESERVED_LENGTH; } public static int getServerReservedLength() { return SERVER_RESERVED_LENGTH; } public boolean isSpotFilm() { return spotFilm; } public static int getLength() { return length; } public static void setLength(int length) { FrameHeader.length = length; } } 3.package careray; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import javax.swing.DefaultBoundedRangeModel; import javax.swing.JScrollBar; import org.apache.log4j.Logger; import careray.fluoro.FixedSizeCircularArray; import careray.fluoro.FluoroGUI; import careray.fluoro.FrameInfo; import careray.structure.Constants; import careray.structure.header.FrameHeader; import careray.structure.header.SeqFileHeader; import careray.utils.RawImgUtils; import ij.ImagePlus; import ij.ImageStack; import ij.io.OpenDialog; import ij.io.RandomAccessStream; public class SeqReader { private static final boolean INTEL_BYTE_ORDER = true; private String directory; private String name; private InputStream in; /** * log recorder */ private static Logger logger = Logger.getLogger(SeqReader.class); public SeqReader(String directory, String name) { this.directory = directory; this.name = name; } public SeqReader() { } public ImagePlus read() { if (name == null || directory == null) { OpenDialog od = new OpenDialog("Open Raw...", ""); directory = od.getDirectory(); name = od.getFileName(); if (name == null || directory == null) return null; } try { // get the inputStream to read the file in = new RandomAccessStream(new RandomAccessFile(new File(directory, name), "r")); SeqFileHeader header = readFileHeader(); ImagePlus imp = readFrames(header); in.close(); return imp; } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } private SeqFileHeader readFileHeader() throws IOException { short[] headerData = RawImgUtils.read16bitData(in, SeqFileHeader.FILE_HEADER_LENGTH, INTEL_BYTE_ORDER); SeqFileHeader header = new SeqFileHeader(); header.setData(headerData); header.parse(); logger.info("Seq file header: " + header.toString()); return header; } private ImagePlus readFrames(SeqFileHeader header) throws IOException { int width = header.getImgWidth(); int height = header.getImgHeight(); int frameNum = header.getFrameNum(); int byteCount = width * height * Constants.BYTES_PER_SHORT; ImageStack stack = new ImageStack(width, height, StartWrap.isCareImage() ? frameNum : 1); ImagePlus imp = null; FixedSizeCircularArray frameBuffer = new FixedSizeCircularArray(frameNum, width, height); FrameHeader frameHeader; FrameInfo frame; int firstFrameID = 0; for (int i = 0; i < frameNum; i++) { frame = frameBuffer.nextToInit(); frameHeader = frame.getHeader(); RawImgUtils.read16bitData(in, header.getFrameHeaderSize(), INTEL_BYTE_ORDER, frameHeader.getData()); frameHeader.parse(); frame.setFrameID(frameHeader.getFrameID() == 0 ? i + 1 : frameHeader.getFrameID()); RawImgUtils.read16bitData(in, byteCount, INTEL_BYTE_ORDER, frame.getFrameData()); stack.setPixels(frame.getFrameData(), StartWrap.isCareImage() ? i + 1 : 1); if (0 == i) { firstFrameID = frameHeader.getFrameID(); imp = new ImagePlus(name, stack, frameNum, true); } } imp.setFrameBuffer(frameBuffer); imp.show(); if (StartWrap.isFluoroApp()) { JScrollBar scrollBar = FluoroGUI.getInstance().getJScrollBar1(); DefaultBoundedRangeModel model = new DefaultBoundedRangeModel(firstFrameID, 1, firstFrameID, firstFrameID + frameNum); scrollBar.setModel(model); } return imp; } } 4.package careray.fluoro; import careray.structure.header.FrameHeader; public class FrameInfo { private short[] frameData; private FrameHeader header; private int frameID; public FrameInfo(int frameID, FrameHeader header, short[] frameData) { this.frameID = frameID; this.header = header; this.frameData = frameData; } public FrameInfo(int imgWidth, int imgHeight) { this.header = new FrameHeader(); this.frameData = new short[imgWidth * imgHeight]; } public short[] getFrameData() { return frameData; } public void setFrameData(short[] frameData) { this.frameData = frameData; } public FrameHeader getHeader() { return header; } public void setHeader(FrameHeader header) { this.header = header; } public int getFrameID() { return frameID; } public void setFrameID(int frameID) { this.frameID = frameID; } } 5.package careray; import java.io.BufferedOutputStream; import java.io.DataOutputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import javax.swing.JDialog; import org.apache.log4j.Logger; import careray.fluoro.FrameInfo; import careray.structure.Constants; import careray.structure.header.FrameHeader; import careray.structure.header.SeqFileHeader; import careray.utils.RawImgUtils; import ij.ImagePlus; import ij.io.FileInfo; import ij.io.ImageWriter; public class SeqWriter { /** * log recorder */ private static Logger logger = Logger.getLogger(SeqWriter.class); private FileInfo fi; private long startTime, endTime; public SeqWriter(ImagePlus imp) { fi = imp.getFileInfo(); fi.intelByteOrder = true; if (imp.getFrameBuffer() != null) { ArrayList<FrameInfo> list = imp.getFrameBuffer().asArrayList(); int minFrameID = 1; int maxFrameID = fi.nImages; if (imp.isHasFrameHeader() && list.get(0).getFrameID() != 0) { minFrameID = list.get(0).getFrameID(); maxFrameID = list.get(list.size() - 1).getFrameID(); } DynamicImgSaveDialog dialog = new DynamicImgSaveDialog(1, maxFrameID - minFrameID + 1, imp.getTitle(), Constants.POSTFIX_SEQ); dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); dialog.setLocationRelativeTo(null); dialog.setVisible(true); fi.directory = dialog.getPath(); if (dialog.getPath() == null) return; if (!fi.directory.endsWith(Constants.POSTFIX_SEQ)) fi.directory += Constants.POSTFIX_SEQ; int startFrameID = dialog.getStartFrameID() + minFrameID - 1; int endFrameID = dialog.getEndFrameID() + minFrameID - 1; fi.nImages = endFrameID - startFrameID + 1; Object[] data = new Object[fi.nImages]; int frameID; int i = 0; FrameInfo frameInfo; for (Iterator<FrameInfo> iter = list.iterator(); iter.hasNext();) { frameInfo = iter.next(); frameID = frameInfo.getFrameID(); if (frameID == 0) frameID = i + 1; if (frameID >= startFrameID && frameID <= endFrameID) { data[i++] = new short[][] {(short[])frameInfo.getHeader().getData(), (short[])frameInfo.getFrameData()}; } } // calculate the absolute time of the first frame if (imp.getAcqStartTime() > 0) { startTime = list.get(0).getHeader().getAbsAcqTime(); endTime = list.get(list.size() - 1).getHeader().getAbsAcqTime(); } fi.pixels = data; } } public void write() { if (fi.directory == null) return; try { // create an outputStream DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(fi.directory))); // 1. write header into file writeHeader(out); // write data of every frame into file writeData(out); out.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private void writeData(DataOutputStream out) throws IOException { new ImageWriter(fi).writeSeq(out); } private void writeHeader(DataOutputStream out) throws IOException { SeqFileHeader fileHeader = new SeqFileHeader(); fileHeader.setImgWidth(fi.width); fileHeader.setImgHeight(fi.height); fileHeader.setFrameNum(fi.nImages); fileHeader.setFrameRate(12.5f); if (startTime > 0 && endTime > 0) { SimpleDateFormat dFormat = new SimpleDateFormat(Constants.TIME_FORMAT_WITH_MS); fileHeader.setStartTime(dFormat.format(new Date(startTime))); fileHeader.setEndTime(dFormat.format(new Date(endTime))); } int fileSize = SeqFileHeader.FILE_HEADER_LENGTH + (FrameHeader.FRAME_HEADER_LENGTH + fi.width * fi.height * Constants.BYTES_PER_SHORT) * fi.nImages; fileHeader.setFileSize(fileSize); RawImgUtils.write16BitData(out, fileHeader.getData(), SeqFileHeader.FILE_HEADER_LENGTH, true); } }
最新发布
07-23
<think>嗯,用户让我把五个Java类转换成C++类。首先,我需要仔细分析每个Java类的结构和功能,然后考虑如何在C++中实现类似的功能。 第一个类是SeqFileHeader,它继承自Header。Java中的继承在C++中可以通过类继承实现。注意到这个类里有很多静态的LinkedHashMap,用来存储属性及其大小。C++中没有LinkedHashMap,但可以用std::map或者std::unordered_map,不过可能需要保持插入顺序,所以可能需要用std::map,或者使用第三方库如boost::multi_index。不过标准库中没有直接对应的,可能需要用vector保存键的顺序,或者用C++11后的ordered_map实现。这里可能需要自定义一个结构来维护顺序。 然后是FrameHeader类,同样继承自Header。里面有一些静态常量和静态属性映射。C++中静态成员变量需要在类外初始化,需要注意初始化顺序。另外,parse方法处理数据,涉及到位操作和数据类型转换,这部分在C++中需要特别注意字节顺序和数据类型的大小,比如使用uint32_t等固定大小的类型。 第三个类是SeqReader,负责文件并解析序列图像。这里用到了ImagePlus、ImageStack等ImageJ相关的类,这些在C++中可能需要替换成其他图像处理库,比如OpenCV或者自定义的类。另外,输入流使用的是RandomAccessStream和RandomAccessFile,C++中可以用fstream配合seekg等方法实现随机访问。 第四个类FrameInfo,比较简单,包含帧数据和头信息。在C++中可以直接用类或结构体,注意构造函数和成员变量的初始化。 第五个类SeqWriter,处理文件,涉及到文件对话框和数据入。Java的JDialog在C++中可以用Qt或者其他的GUI库替代,但用户可能希望保持控制台应用或者简化这部分,可能需要处理文件路径选择,这里可能需要使用跨平台库如Qt或者简化为手动输入路径。 接下来需要考虑各个类之间的依赖关系,比如Header类在Java中是基类,C++中需要先定义Header类,然后SeqFileHeader和FrameHeader继承它。可能还需要处理工具类如RawImgUtils中的方法,比如16位数据,字节顺序转换等,这些在C++中需要相应的函数实现。 另外,Java中的short数组在C++中可以用std::vector<short>或者std::array,但根据上下文,可能动态大小更适合vector。对于数据解析,需要注意内存对齐和类型转换,可能需要使用memcpy或者位操作。 对于字符串处理,Java中的String在C++中用std::string,需要注意编码问题,特别是固定长度字符串的处理,可能需要填充或截断。 静态成员变量如FILE_HEADER_LENGTH在C++中需要在类外初始化,或者使用constexpr如果可能。例如,static const int FILE_HEADER_LENGTH = 1024; 在C++11中可以在类内初始化,但如果是较旧的标准可能需要类外初始化。 关于异常处理,Java中抛出IOException,C++中可以抛出std::ios_base::failure或者自定义异常,或者使用错误码,这取决于设计。 在转换过程中,还需要处理Java特有的类如Logger,可以用C++的日志库如log4cpp或者简单的替换为输出到控制台。 最后,整个转换需要确保功能等价,包括数据结构的正确转换、文件逻辑的正确实现,以及类之间的交互。可能需要编测试用例来验证转换后的C++类是否正确。 </think>以下是将5个Java类转换为C++类的实现: ```cpp // Constants.h #pragma once #include <cstdint> namespace Constants { constexpr int BYTES_PER_SHORT = 2; constexpr int ENDIAN_INTEL = 1; const char NEW_LINE[] = "\n"; constexpr int POSTFIX_SEQ = ".seq"; const char TIME_FORMAT_WITH_MS[] = "yyyy-MM-dd HH:mm:ss.SSS"; } ``` ```cpp // Header.h #pragma once #include <vector> #include <string> #include <map> class Header { protected: std::vector<uint16_t> data; // Helper methods std::string getString(const std::vector<uint16_t>& data, int offset, int length); uint32_t getU32ByLE(const std::vector<uint16_t>& data, int offset); float getFloatByLE(const std::vector<uint16_t>& data, int offset); std::vector<uint16_t> getShortData(int value); std::vector<uint16_t> getShortData(float value); std::vector<uint16_t> getShortData(const std::string& str); }; ``` ```cpp // SeqFileHeader.h #pragma once #include "Header.h" #include <map> #include <string> #include <vector> class SeqFileHeader : public Header { private: static const std::string TYPE_CODE_SEQ; static constexpr int FILE_HEADER_LENGTH = 1024; // Property maps static const std::map<std::string, int> IMAGE_PROPERTIES; static const std::map<std::string, int> DETECTOR_PROPERTIES; static const std::map<std::string, int> API_PROPERTIES; // Member variables std::string typeCode; int fileHeaderSize; int fileSize; int imgWidth; int imgHeight; int bitDepth; int storageType; int endianType; int compressType; std::string startTime; std::string endTime; int frameNum; float frameRate; int frameHeaderSize; std::string machineID; std::string hwVersion; std::string fmVersion; int modeID; int triggerMode; int exposeWin; std::string swVersion; std::string GWS_IP; int offsetCorrected; int gainCorrected; int defectCorrected; int denoised; int DGC; int resized; int LUT; std::string description; std::vector<uint16_t> generateHeaderData(); public: SeqFileHeader(); // Getters and setters const std::vector<uint16_t>& getData(); void parse(); void setData(const std::vector<uint16_t>& data); // Property accessors std::string getTypeCode() const { return typeCode; } // ...其他getter/setter }; ``` ```cpp // FrameHeader.h #pragma once #include "Header.h" #include <map> #include <string> class FrameHeader : public Header { private: static constexpr int FRAME_HEADER_LENGTH = 256; static constexpr int HEADER_RESERVED_LENGTH = 6; static constexpr int DETECTOR_RESERVED_LENGTH = 126; static constexpr int SERVER_RESERVED_LENGTH = 75; static const std::map<std::string, int> PROPERTIES; // Member variables std::vector<uint16_t> data; int length; bool spotFilm; int frameID; int64_t absAcqTime; int relativeAcqTime; int blockLen; float avgTemp; float maxTemp; float vcmp; float vbias; int gain; int modeID; int detectorIndex; int qualityType; int offsetFlag; int gainFlag; int defectFlag; int crc; public: FrameHeader(); void parse(const std::vector<uint16_t>& data); std::string toString() const; // Getters and setters const std::vector<uint16_t>& getData() const { return data; } // ...其他getter/setter }; ``` ```cpp // FrameInfo.h #pragma once #include "FrameHeader.h" class FrameInfo { private: std::vector<uint16_t> frameData; FrameHeader header; int frameID; public: FrameInfo(int frameID, const FrameHeader& header, const std::vector<uint16_t>& frameData); FrameInfo(int imgWidth, int imgHeight); // Getters and setters const std::vector<uint16_t>& getFrameData() const { return frameData; } void setFrameData(const std::vector<uint16_t>& data) { frameData = data; } const FrameHeader& getHeader() const { return header; } void setHeader(const FrameHeader& h) { header = h; } int getFrameID() const { return frameID; } void setFrameID(int id) { frameID = id; } }; ``` ```cpp // SeqReaderWriter.h #pragma once #include <string> #include <vector> #include <fstream> #include "SeqFileHeader.h" #include "FrameInfo.h" class SeqReader { private: static constexpr bool INTEL_BYTE_ORDER = true; std::string directory; std::string name; std::ifstream in; public: SeqReader(const std::string& dir, const std::string& nm) : directory(dir), name(nm) {} ImagePlus read(); // 需要定义ImagePlus类 private: SeqFileHeader readFileHeader(); ImagePlus readFrames(const SeqFileHeader& header); }; class SeqWriter { private: struct FileInfo { int width; int height; int nImages; bool intelByteOrder; std::string directory; std::string title; } fi; long startTime, endTime; public: SeqWriter(const ImagePlus& imp); void write(); private: void writeData(std::ofstream& out); void writeHeader(std::ofstream& out); }; ``` ```cpp // RawImgUtils.h #pragma once #include <vector> #include <fstream> class RawImgUtils { public: static std::vector<uint16_t> read16bitData(std::ifstream& in, int length, bool intelByteOrder); static void write16BitData(std::ofstream& out, const std::vector<uint16_t>& data, int length, bool intelByteOrder); }; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值