জাভাতে বাইট অর্ডার চিহ্ন স্ক্রু আপ ফাইল রিডিং


107

আমি জাভা ব্যবহার করে সিএসভি ফাইলগুলি পড়ার চেষ্টা করছি। কিছু ফাইলের শুরুর দিকে বাইট অর্ডার চিহ্ন থাকতে পারে তবে সমস্তটি নয়। উপস্থিত থাকাকালীন, বাইট ক্রমটি প্রথম পংক্তির বাকী অংশের সাথে পড়া হয়, সুতরাং স্ট্রিংয়ের তুলনায় সমস্যা তৈরি করে।

বাইট অর্ডার চিহ্নটি উপস্থিত থাকার পরে কি কোনও সহজ উপায় আছে?

ধন্যবাদ!


উত্তর:


114

সম্পাদনা : আমি গিটহাবের উপর একটি যথাযথ প্রকাশ করেছি: https://github.com/gpakosz/UnicodeBOMInputStream


আমি কিছুক্ষণ আগে কোড করেছিলাম এমন একটি ক্লাস এখানে রয়েছে, আমি কেবল পেষ্ট করার আগে প্যাকেজের নাম সম্পাদনা করেছি। বিশেষ কিছু নয়, এটি সান এর বাগ ডাটাবেসে পোস্ট হওয়া সমাধানগুলির সাথে বেশ মিল। এটি আপনার কোডটিতে অন্তর্ভুক্ত করুন এবং আপনি ভাল আছেন।

/* ____________________________________________________________________________
 * 
 * File:    UnicodeBOMInputStream.java
 * Author:  Gregory Pakosz.
 * Date:    02 - November - 2005    
 * ____________________________________________________________________________
 */
package com.stackoverflow.answer;

import java.io.IOException;
import java.io.InputStream;
import java.io.PushbackInputStream;

/**
 * The <code>UnicodeBOMInputStream</code> class wraps any
 * <code>InputStream</code> and detects the presence of any Unicode BOM
 * (Byte Order Mark) at its beginning, as defined by
 * <a href="http://www.faqs.org/rfcs/rfc3629.html">RFC 3629 - UTF-8, a transformation format of ISO 10646</a>
 * 
 * <p>The
 * <a href="http://www.unicode.org/unicode/faq/utf_bom.html">Unicode FAQ</a>
 * defines 5 types of BOMs:<ul>
 * <li><pre>00 00 FE FF  = UTF-32, big-endian</pre></li>
 * <li><pre>FF FE 00 00  = UTF-32, little-endian</pre></li>
 * <li><pre>FE FF        = UTF-16, big-endian</pre></li>
 * <li><pre>FF FE        = UTF-16, little-endian</pre></li>
 * <li><pre>EF BB BF     = UTF-8</pre></li>
 * </ul></p>
 * 
 * <p>Use the {@link #getBOM()} method to know whether a BOM has been detected
 * or not.
 * </p>
 * <p>Use the {@link #skipBOM()} method to remove the detected BOM from the
 * wrapped <code>InputStream</code> object.</p>
 */
public class UnicodeBOMInputStream extends InputStream
{
  /**
   * Type safe enumeration class that describes the different types of Unicode
   * BOMs.
   */
  public static final class BOM
  {
    /**
     * NONE.
     */
    public static final BOM NONE = new BOM(new byte[]{},"NONE");

    /**
     * UTF-8 BOM (EF BB BF).
     */
    public static final BOM UTF_8 = new BOM(new byte[]{(byte)0xEF,
                                                       (byte)0xBB,
                                                       (byte)0xBF},
                                            "UTF-8");

    /**
     * UTF-16, little-endian (FF FE).
     */
    public static final BOM UTF_16_LE = new BOM(new byte[]{ (byte)0xFF,
                                                            (byte)0xFE},
                                                "UTF-16 little-endian");

    /**
     * UTF-16, big-endian (FE FF).
     */
    public static final BOM UTF_16_BE = new BOM(new byte[]{ (byte)0xFE,
                                                            (byte)0xFF},
                                                "UTF-16 big-endian");

    /**
     * UTF-32, little-endian (FF FE 00 00).
     */
    public static final BOM UTF_32_LE = new BOM(new byte[]{ (byte)0xFF,
                                                            (byte)0xFE,
                                                            (byte)0x00,
                                                            (byte)0x00},
                                                "UTF-32 little-endian");

    /**
     * UTF-32, big-endian (00 00 FE FF).
     */
    public static final BOM UTF_32_BE = new BOM(new byte[]{ (byte)0x00,
                                                            (byte)0x00,
                                                            (byte)0xFE,
                                                            (byte)0xFF},
                                                "UTF-32 big-endian");

    /**
     * Returns a <code>String</code> representation of this <code>BOM</code>
     * value.
     */
    public final String toString()
    {
      return description;
    }

    /**
     * Returns the bytes corresponding to this <code>BOM</code> value.
     */
    public final byte[] getBytes()
    {
      final int     length = bytes.length;
      final byte[]  result = new byte[length];

      // Make a defensive copy
      System.arraycopy(bytes,0,result,0,length);

      return result;
    }

    private BOM(final byte bom[], final String description)
    {
      assert(bom != null)               : "invalid BOM: null is not allowed";
      assert(description != null)       : "invalid description: null is not allowed";
      assert(description.length() != 0) : "invalid description: empty string is not allowed";

      this.bytes          = bom;
      this.description  = description;
    }

            final byte    bytes[];
    private final String  description;

  } // BOM

  /**
   * Constructs a new <code>UnicodeBOMInputStream</code> that wraps the
   * specified <code>InputStream</code>.
   * 
   * @param inputStream an <code>InputStream</code>.
   * 
   * @throws NullPointerException when <code>inputStream</code> is
   * <code>null</code>.
   * @throws IOException on reading from the specified <code>InputStream</code>
   * when trying to detect the Unicode BOM.
   */
  public UnicodeBOMInputStream(final InputStream inputStream) throws  NullPointerException,
                                                                      IOException

  {
    if (inputStream == null)
      throw new NullPointerException("invalid input stream: null is not allowed");

    in = new PushbackInputStream(inputStream,4);

    final byte  bom[] = new byte[4];
    final int   read  = in.read(bom);

    switch(read)
    {
      case 4:
        if ((bom[0] == (byte)0xFF) &&
            (bom[1] == (byte)0xFE) &&
            (bom[2] == (byte)0x00) &&
            (bom[3] == (byte)0x00))
        {
          this.bom = BOM.UTF_32_LE;
          break;
        }
        else
        if ((bom[0] == (byte)0x00) &&
            (bom[1] == (byte)0x00) &&
            (bom[2] == (byte)0xFE) &&
            (bom[3] == (byte)0xFF))
        {
          this.bom = BOM.UTF_32_BE;
          break;
        }

      case 3:
        if ((bom[0] == (byte)0xEF) &&
            (bom[1] == (byte)0xBB) &&
            (bom[2] == (byte)0xBF))
        {
          this.bom = BOM.UTF_8;
          break;
        }

      case 2:
        if ((bom[0] == (byte)0xFF) &&
            (bom[1] == (byte)0xFE))
        {
          this.bom = BOM.UTF_16_LE;
          break;
        }
        else
        if ((bom[0] == (byte)0xFE) &&
            (bom[1] == (byte)0xFF))
        {
          this.bom = BOM.UTF_16_BE;
          break;
        }

      default:
        this.bom = BOM.NONE;
        break;
    }

    if (read > 0)
      in.unread(bom,0,read);
  }

  /**
   * Returns the <code>BOM</code> that was detected in the wrapped
   * <code>InputStream</code> object.
   * 
   * @return a <code>BOM</code> value.
   */
  public final BOM getBOM()
  {
    // BOM type is immutable.
    return bom;
  }

  /**
   * Skips the <code>BOM</code> that was found in the wrapped
   * <code>InputStream</code> object.
   * 
   * @return this <code>UnicodeBOMInputStream</code>.
   * 
   * @throws IOException when trying to skip the BOM from the wrapped
   * <code>InputStream</code> object.
   */
  public final synchronized UnicodeBOMInputStream skipBOM() throws IOException
  {
    if (!skipped)
    {
      in.skip(bom.bytes.length);
      skipped = true;
    }
    return this;
  }

  /**
   * {@inheritDoc}
   */
  public int read() throws IOException
  {
    return in.read();
  }

  /**
   * {@inheritDoc}
   */
  public int read(final byte b[]) throws  IOException,
                                          NullPointerException
  {
    return in.read(b,0,b.length);
  }

  /**
   * {@inheritDoc}
   */
  public int read(final byte b[],
                  final int off,
                  final int len) throws IOException,
                                        NullPointerException
  {
    return in.read(b,off,len);
  }

  /**
   * {@inheritDoc}
   */
  public long skip(final long n) throws IOException
  {
    return in.skip(n);
  }

  /**
   * {@inheritDoc}
   */
  public int available() throws IOException
  {
    return in.available();
  }

  /**
   * {@inheritDoc}
   */
  public void close() throws IOException
  {
    in.close();
  }

  /**
   * {@inheritDoc}
   */
  public synchronized void mark(final int readlimit)
  {
    in.mark(readlimit);
  }

  /**
   * {@inheritDoc}
   */
  public synchronized void reset() throws IOException
  {
    in.reset();
  }

  /**
   * {@inheritDoc}
   */
  public boolean markSupported() 
  {
    return in.markSupported();
  }

  private final PushbackInputStream in;
  private final BOM                 bom;
  private       boolean             skipped = false;

} // UnicodeBOMInputStream

এবং আপনি এটি এভাবে ব্যবহার করছেন:

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;

public final class UnicodeBOMInputStreamUsage
{
  public static void main(final String[] args) throws Exception
  {
    FileInputStream fis = new FileInputStream("test/offending_bom.txt");
    UnicodeBOMInputStream ubis = new UnicodeBOMInputStream(fis);

    System.out.println("detected BOM: " + ubis.getBOM());

    System.out.print("Reading the content of the file without skipping the BOM: ");
    InputStreamReader isr = new InputStreamReader(ubis);
    BufferedReader br = new BufferedReader(isr);

    System.out.println(br.readLine());

    br.close();
    isr.close();
    ubis.close();
    fis.close();

    fis = new FileInputStream("test/offending_bom.txt");
    ubis = new UnicodeBOMInputStream(fis);
    isr = new InputStreamReader(ubis);
    br = new BufferedReader(isr);

    ubis.skipBOM();

    System.out.print("Reading the content of the file after skipping the BOM: ");
    System.out.println(br.readLine());

    br.close();
    isr.close();
    ubis.close();
    fis.close();
  }

} // UnicodeBOMInputStreamUsage

2
দীর্ঘ স্ক্রোলিং অঞ্চলগুলির জন্য দুঃখিত, খুব খারাপ কোনও সংযুক্তি বৈশিষ্ট্য নেই
গ্রেগরি পাকোস্জ

ধন্যবাদ গ্রেগরি, আমি যা খুঁজছি ঠিক এটিই।
টম

3
এটি মূল জাভা
এপিআইতে

7
10 বছর কেটে গেছে এবং আমি এর জন্য এখনও কর্মফল পাচ্ছি: ডি আমি আপনার দিকে জাভা খুঁজছি!
গ্রেগরি পাকোস্

1
উত্সাহিত করা হয়েছে কারণ উত্তর ফাইলটি ইনপুট স্ট্রিমটিকে ডিফল্টরূপে বিওএম বাতিল করার বিকল্প সরবরাহ করে না সে সম্পর্কিত ইতিহাস সরবরাহ করে।
এমএক্সএলডিভস

94

এ্যাপাচি কমন্স আই গ্রন্থাগার একটি হয়েছে InputStreamযে সনাক্ত করা এবং করতে বাতিল BOMs: BOMInputStream(javadoc) :

BOMInputStream bomIn = new BOMInputStream(in);
int firstNonBOMByte = bomIn.read(); // Skips BOM
if (bomIn.hasBOM()) {
    // has a UTF-8 BOM
}

আপনার যদি আলাদা আলাদা এনকোডিংগুলি সনাক্ত করতে হয় তবে এটি বিভিন্ন বিভিন্ন বাইট-অর্ডার চিহ্নগুলির মধ্যেও পার্থক্য করতে পারে, যেমন ইউটিএফ -8 বনাম ইউটিএফ -16 বড় + ছোট এন্ডিয়ান - উপরের ডক লিঙ্কে বিশদ। তারপরে আপনি স্ট্রিমটি ডিকোড করতে ByteOrderMarkএকটি চয়ন Charsetকরতে সনাক্তকারীটিকে ব্যবহার করতে পারেন । (আপনার যদি এই সমস্ত কার্যকারিতা প্রয়োজন হয় তবে এটি করার আরও একটি সহজ উপায় আছে - সম্ভবত বালুসকের উত্তরে ইউনিকোডেরীডার?) উত্তর। মনে রাখবেন, সাধারণভাবে, কিছু বাইট কী কী এনকডিং রয়েছে তা সনাক্ত করার খুব ভাল উপায় নেই তবে স্ট্রিমটি যদি কোনও বিওএম দিয়ে শুরু হয় তবে দৃশ্যত এটি সহায়ক হতে পারে।

সম্পাদনা করুন : আপনি যদি ইউটিএফ -16, ইউটিএফ -32, ইত্যাদিতে বিওএম সনাক্ত করতে চান তবে কনস্ট্রাক্টরটি হ'ল:

new BOMInputStream(is, ByteOrderMark.UTF_8, ByteOrderMark.UTF_16BE,
        ByteOrderMark.UTF_16LE, ByteOrderMark.UTF_32BE, ByteOrderMark.UTF_32LE)

@ মার্টিন-চার্লসওয়ার্থ এর মন্তব্য :) উপভোগ করুন


শুধু বিওএম এড়িয়ে যান। ব্যবহারের 99% ক্ষেত্রে উপযুক্ত সমাধান হওয়া উচিত।
atamanroman

7
আমি এই উত্তরটি সফলভাবে ব্যবহার করেছি। তবে, আমি booleanবিওএমকে অন্তর্ভুক্ত করব না বা বাদ দেবে কিনা তা উল্লেখ করার জন্য আমি শ্রদ্ধার সাথে যুক্তিটি যুক্ত করব । উদাহরণ:BOMInputStream bomIn = new BOMInputStream(in, false); // don't include the BOM
কেভিন মেরেডিথ

19
আমি আরও যুক্ত করব যে এটি কেবল ইউটিএফ -8 বিওএম সনাক্ত করে। আপনি যদি সমস্ত ইউটিএফ-এক্স বিওএম সনাক্ত করতে চান তবে আপনাকে সেগুলি বিএমআইএনপুটস্ট্রিম কনস্ট্রাক্টরের কাছে প্রেরণ করতে হবে। BOMInputStream bomIn = new BOMInputStream(is, ByteOrderMark.UTF_8, ByteOrderMark.UTF_16BE, ByteOrderMark.UTF_16LE, ByteOrderMark.UTF_32BE, ByteOrderMark.UTF_32LE);
মার্টিন চার্লসওয়ার্থ

@ কেভিন ম্যারেডিথের মন্তব্য হিসাবে, আমি জোর দিয়ে বলতে চাই যে বুলিয়ান সহ নির্মাতা আরও পরিষ্কার, তবে জাভাডকের পরামর্শ অনুসারে ডিফল্ট কনস্ট্রাক্টর ইতিমধ্যে ইউটিএফ -8 বিওএম থেকে মুক্তি পেয়েছে:BOMInputStream(InputStream delegate) Constructs a new BOM InputStream that excludes a ByteOrderMark.UTF_8 BOM.
ওয়েস্টার্নগান

এড়িয়ে যাওয়া আমার বেশিরভাগ সমস্যার সমাধান করে। যদি আমার ফাইলটি কোনও বিওএম ইউটিএফ_16 বিই দিয়ে শুরু হয়, তবে আমি কি বিওএমকে এড়িয়ে এবং ফাইলটি ইউটিএফ_ 8 হিসাবে পড়ে একটি ইনপুট রিডার তৈরি করতে পারি? এখন পর্যন্ত এটি কাজ করে, আমি বুঝতে চাই কোন প্রান্তের মামলা আছে কিনা? আগাম ধন্যবাদ.
ভাস্কর

31

আরও সহজ সমাধান:

public class BOMSkipper
{
    public static void skip(Reader reader) throws IOException
    {
        reader.mark(1);
        char[] possibleBOM = new char[1];
        reader.read(possibleBOM);

        if (possibleBOM[0] != '\ufeff')
        {
            reader.reset();
        }
    }
}

ব্যবহারের নমুনা:

BufferedReader input = new BufferedReader(new InputStreamReader(new FileInputStream(file), fileExpectedCharset));
BOMSkipper.skip(input);
//Now UTF prefix not present:
input.readLine();
...

এটি সমস্ত 5 ইউটিএফ এনকোডিংয়ের সাথে কাজ করে!


1
খুব সুন্দর আন্দ্রেই। তবে কেন আপনি এটি ব্যাখ্যা করতে পারেন? 0xFEFF প্যাটার্নটি কীভাবে সফলভাবে ইউটিএফ -8 ফাইলগুলির সাথে মেলে যা 2 এর পরিবর্তে আলাদা প্যাটার্ন এবং 3 বাইট বলে মনে হচ্ছে? এবং কীভাবে সেই প্যাটার্নটি ইউটিএফ 16 এবং ইউটিএফ 32 এর উভয় সমাপ্তির সাথে মেলে?
ওয়াহিদ পজিরান্দেহে

1
যেমন আপনি দেখতে পাচ্ছেন - আমি বাইট স্ট্রিম ব্যবহার করি না তবে প্রত্যাশিত চরসেট দিয়ে অক্ষর প্রবাহটি খোল opened সুতরাং এই স্ট্রিমের প্রথম চরিত্রটি যদি বিওএম হয় - তবে আমি এড়িয়ে যাব। প্রতিটি এনকোডিংয়ের জন্য বিওএমের বিভিন্ন বাইট উপস্থাপনা থাকতে পারে তবে এটি একটি চরিত্র। দয়া করে এই নিবন্ধটি পড়ুন, এটি আমাকে সহায়তা করে: joelonsoftware.com/articles/Unicode.html

চমৎকার সমাধান, পড়ার আগে স্কিপ পদ্ধতিতে আইওএক্সেপশন এড়াতে ফাইলটি খালি নেই কিনা তা পরীক্ষা করে দেখুন। আপনি যদি (রিডার। রেডি ()) {রিডার.ড্রেড (সম্ভাব্য বিএম) ... calling
তুষার

আমি দেখতে পাচ্ছি আপনি 0xFE 0xFF কভার করেছেন, যা ইউটিএফ -16 বিই এর বাইট অর্ডার চিহ্ন। তবে, যদি প্রথম 3 বাইট 0xEF 0xBB 0xEF হয়? (ইউটিএফ -8 এর জন্য বাইট অর্ডার চিহ্ন)। আপনি দাবি করেন যে এটি সমস্ত ইউটিএফ -8 ফর্ম্যাটের জন্য কাজ করে। কোনটি সত্য হতে পারে (আমি আপনার কোড পরীক্ষা করিনি) তবে এটি কীভাবে কাজ করবে?
বিভিডিবি

1
ওয়াহিদের কাছে আমার উত্তর দেখুন: আমি বাইট স্ট্রিমটি নয় বরং চরিত্রের প্রবাহটি খুলি এবং এ থেকে একটি অক্ষর পড়ি। ফাইলের জন্য ইউটিএফ এনকোডিংটি কী ব্যবহার করেছে তা মনে করবেন না - বোম উপসর্গ বিভিন্ন বাইটের গণনা দ্বারা উপস্থাপন করতে পারে তবে অক্ষরের দিক থেকে এটি কেবল একটি অক্ষর

24

গুগল ডেটা এপিআই- তে একটি রয়েছে UnicodeReaderযা স্বয়ংক্রিয়ভাবে এনকোডিং সনাক্ত করে।

আপনি এর পরিবর্তে এটি ব্যবহার করতে পারেন InputStreamReader। এখানে এর উত্সটি একটি সামান্য সংক্ষিপ্ত - এক্সট্রাক্ট যা বেশ সোজা:

public class UnicodeReader extends Reader {
    private static final int BOM_SIZE = 4;
    private final InputStreamReader reader;

    /**
     * Construct UnicodeReader
     * @param in Input stream.
     * @param defaultEncoding Default encoding to be used if BOM is not found,
     * or <code>null</code> to use system default encoding.
     * @throws IOException If an I/O error occurs.
     */
    public UnicodeReader(InputStream in, String defaultEncoding) throws IOException {
        byte bom[] = new byte[BOM_SIZE];
        String encoding;
        int unread;
        PushbackInputStream pushbackStream = new PushbackInputStream(in, BOM_SIZE);
        int n = pushbackStream.read(bom, 0, bom.length);

        // Read ahead four bytes and check for BOM marks.
        if ((bom[0] == (byte) 0xEF) && (bom[1] == (byte) 0xBB) && (bom[2] == (byte) 0xBF)) {
            encoding = "UTF-8";
            unread = n - 3;
        } else if ((bom[0] == (byte) 0xFE) && (bom[1] == (byte) 0xFF)) {
            encoding = "UTF-16BE";
            unread = n - 2;
        } else if ((bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE)) {
            encoding = "UTF-16LE";
            unread = n - 2;
        } else if ((bom[0] == (byte) 0x00) && (bom[1] == (byte) 0x00) && (bom[2] == (byte) 0xFE) && (bom[3] == (byte) 0xFF)) {
            encoding = "UTF-32BE";
            unread = n - 4;
        } else if ((bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE) && (bom[2] == (byte) 0x00) && (bom[3] == (byte) 0x00)) {
            encoding = "UTF-32LE";
            unread = n - 4;
        } else {
            encoding = defaultEncoding;
            unread = n;
        }

        // Unread bytes if necessary and skip BOM marks.
        if (unread > 0) {
            pushbackStream.unread(bom, (n - unread), unread);
        } else if (unread < -1) {
            pushbackStream.unread(bom, 0, 0);
        }

        // Use given encoding.
        if (encoding == null) {
            reader = new InputStreamReader(pushbackStream);
        } else {
            reader = new InputStreamReader(pushbackStream, encoding);
        }
    }

    public String getEncoding() {
        return reader.getEncoding();
    }

    public int read(char[] cbuf, int off, int len) throws IOException {
        return reader.read(cbuf, off, len);
    }

    public void close() throws IOException {
        reader.close();
    }
}

দেখে মনে হচ্ছে লিঙ্কটি গুগল ডেটা এপিআই হ'ল? এখনই গুগল ডেটা এপিআইয়ের সন্ধান করা উচিত কোথায়?
সাউদার 2

1
@ শিচেনলি: জিডিটা এপিআই এর উদ্দেশ্যযুক্ত উদ্দেশ্যে নষ্ট করা হয়েছে। আমি সরাসরি জিডিটা এপিআই ব্যবহার করার পরামর্শ দেওয়ার ইচ্ছা করি নি (ওপি কোনও জিডিটা পরিষেবা ব্যবহার করছে না), তবে আমি আপনার নিজের প্রয়োগের জন্য উত্স কোডটি উদাহরণ হিসাবে গ্রহণ করার ইচ্ছা করি। এ কারণেই আমি এটিকে আমার উত্তরে অন্তর্ভুক্ত করেছি, কপিপস্টের জন্য প্রস্তুত।
বালুসসি

এটিতে একটি বাগ আছে। UTF-32LE কেসটি অ্যাক্সেসযোগ্য। (bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE) && (bom[2] == (byte) 0x00) && (bom[3] == (byte) 0x00)সত্য হওয়ার জন্য , তারপরে ইউটিএফ -16 এলই কেসটি (bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE)ইতিমধ্যে মিলছে।
জোশুয়া টেলর 14

যেহেতু এই কোডটি গুগল ডেটা এপিআই এর, তাই আমি এটি সম্পর্কে 471 ইস্যু পোস্ট করেছি।
জোশুয়া টেলর 14

13

Apache Commons IOলাইব্রেরির BOMInputStream ইতিমধ্যে @rescdsk উল্লেখ করা হয়েছে, কিন্তু আমি দেখতে পাইনি এটি একটি পেতে কিভাবে উল্লেখ InputStream ছাড়া BOM।

স্কালায় আমি এটি কীভাবে করেছি Here

 import java.io._
 val file = new File(path_to_xml_file_with_BOM)
 val fileInpStream = new FileInputStream(file)   
 val bomIn = new BOMInputStream(fileInpStream, 
         false); // false means don't include BOM

একক ARG কন্সট্রাকটর এটা আছে: public BOMInputStream(InputStream delegate) { this(delegate, false, ByteOrderMark.UTF_8); }। এটি UTF-8 BOMডিফল্টরূপে বাদ দেয় ।
ভ্লাদিমির ওয়াগাইতসেভ

ভাল কথা, ভ্লাদিমির আমি দেখতে পাচ্ছি যে এর ডক্সে - Commons.apache.org/proper/commons-io/javadocs/api-2.2/org/… :Constructs a new BOM InputStream that excludes a ByteOrderMark.UTF_8 BOM.
কেভিন মেরেডিথ

4

আপনার ফাইল থেকে BOM অক্ষরগুলি সরাতে, আমি অ্যাপাচি কমন আইও ব্যবহার করে পুনরুদ্ধার করব

public BOMInputStream(InputStream delegate,
              boolean include)
Constructs a new BOM InputStream that detects a a ByteOrderMark.UTF_8 and optionally includes it.
Parameters:
delegate - the InputStream to delegate to
include - true to include the UTF-8 BOM or false to exclude it

সেটটিকে মিথ্যাতে অন্তর্ভুক্ত করুন এবং আপনার BOM টি অক্ষর বাদ দেওয়া হবে।



1

আমারও একই সমস্যা ছিল এবং আমি একগুচ্ছ ফাইলগুলিতে পড়ছি না বলে আমি একটি সহজ সমাধান করেছি। আমি মনে করি যে আমার এনকোডিংটি ইউটিএফ -8 ছিল কারণ যখন আমি এই পৃষ্ঠার সাহায্যে আপত্তিজনক চরিত্রটি প্রিন্ট করেছি: একটি চরিত্রের ইউনিকোড মান পেয়েছি আমি দেখতে পেয়েছি যে এটি ছিল \ufeff। আমি System.out.println( "\\u" + Integer.toHexString(str.charAt(0) | 0x10000).substring(1) );আপত্তিজনক ইউনিকোড মানটি মুদ্রণের জন্য কোডটি ব্যবহার করেছি ।

একবার আমার আপত্তিজনক ইউনিকোড মান পরে, আমি পড়ার আগে আমার ফাইলের প্রথম লাইনে এটি প্রতিস্থাপন করেছি। বিভাগটির ব্যবসায়ের যুক্তি:

String str = reader.readLine().trim();
str = str.replace("\ufeff", "");

এটি আমার সমস্যা সমাধান করেছে। তারপরে আমি কোনও সমস্যা ছাড়াই ফাইলটি প্রসেসিংয়ে যেতে সক্ষম হয়েছি। আমি trim()কেবল হোয়াইটস্পেসের শীর্ষস্থানীয় বা অনুসরণ করার ক্ষেত্রে যুক্ত করেছি , আপনার নির্দিষ্ট প্রয়োজনীয়তাগুলির ভিত্তিতে আপনি এটি করতে বা করতে পারেন।


1
এটি আমার পক্ষে কাজ করে না, তবে আমি .replaceFrst ("\ u00EF \ u00BB \ u00BF", "") যা ব্যবহার করেছিলাম।
স্ট্যাকুমান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.