/* * Copyright 2015 MiLaboratory.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.milaboratory.core.io.sequence.fastq; import com.milaboratory.core.io.CompressionType; import com.milaboratory.core.io.sequence.SingleRead; import com.milaboratory.core.io.sequence.SingleSequenceWriter; import com.milaboratory.core.sequence.NucleotideAlphabet; import com.milaboratory.core.sequence.NucleotideSequence; import com.milaboratory.core.sequence.SequenceQuality; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; public final class SingleFastqWriter implements SingleSequenceWriter { public static final int DEFAULT_BUFFER_SIZE = 131072; final OutputStream outputStream; final QualityFormat qualityFormat; final byte[] buffer; int pointer; public SingleFastqWriter(String fileName) throws IOException { this(new FileOutputStream(fileName), QualityFormat.Phred33, CompressionType.detectCompressionType(fileName), DEFAULT_BUFFER_SIZE); } public SingleFastqWriter(File file) throws IOException { this(new FileOutputStream(file), QualityFormat.Phred33, CompressionType.detectCompressionType(file), DEFAULT_BUFFER_SIZE); } public SingleFastqWriter(OutputStream outputStream) throws IOException { this(outputStream, QualityFormat.Phred33, CompressionType.None, DEFAULT_BUFFER_SIZE); } public SingleFastqWriter(File file, QualityFormat qualityFormat, CompressionType ct) throws IOException { this(new FileOutputStream(file), qualityFormat, ct, DEFAULT_BUFFER_SIZE); } public SingleFastqWriter(String fileName, QualityFormat qualityFormat, CompressionType ct) throws IOException { this(new FileOutputStream(fileName), qualityFormat, ct, DEFAULT_BUFFER_SIZE); } public SingleFastqWriter(OutputStream outputStream, QualityFormat qualityFormat, CompressionType ct) throws IOException { this(outputStream, qualityFormat, ct, DEFAULT_BUFFER_SIZE); } public SingleFastqWriter(OutputStream outputStream, QualityFormat qualityFormat, CompressionType ct, int bufferSize) throws IOException { this.outputStream = ct.createOutputStream(outputStream, bufferSize / 2); this.qualityFormat = qualityFormat; this.buffer = new byte[bufferSize]; } @Override public synchronized void write(SingleRead read) { String description = read.getDescription(); int len = description.length(); flushIfNeededToWrite(len + 1); buffer[pointer++] = '@'; for (int i = 0; i < len; ++i) buffer[pointer++] = (byte) description.charAt(i); NucleotideSequence sequence = read.getData().getSequence(); SequenceQuality quality = read.getData().getQuality(); len = sequence.size(); flushIfNeededToWrite(len + 2); buffer[pointer++] = '\n'; for (int i = 0; i < len; ++i) buffer[pointer++] = NucleotideAlphabet.symbolByteFromCode(sequence.codeAt(i)); buffer[pointer++] = '\n'; flushIfNeededToWrite(len + 3); buffer[pointer++] = '+'; buffer[pointer++] = '\n'; quality.encodeTo(qualityFormat, buffer, pointer); pointer += len; buffer[pointer++] = '\n'; } private void flushIfNeededToWrite(int sizeToWrite) { if (buffer.length - pointer < sizeToWrite) flush(); } @Override public void flush() { try { outputStream.write(buffer, 0, pointer); pointer = 0; } catch (IOException e) { throw new RuntimeException(e); } } @Override public void close() { try { flush(); outputStream.close(); } catch (IOException e) { throw new RuntimeException(e); } } }