আমি কীভাবে একটি জাভা.এল.আর. স্ট্রিং থেকে একটি java.io.Inputstream পেতে পারি?


95

আমার একটি রয়েছে Stringযা আমি একটি হিসাবে ব্যবহার করতে চাই InputStream। জাভা ০.০ এ, আপনি ব্যবহার করতে পারেন java.io.StringBufferInputStream, তবে তা হয়েছে @Deprecrated(সঙ্গত কারণে - আপনি অক্ষর সেট এনকোডিং নির্দিষ্ট করতে পারবেন না):

এই শ্রেণিটি অক্ষরগুলি যথাযথভাবে বাইটে রূপান্তর করে না। জেডিকে ১.১ হিসাবে, স্ট্রিং থেকে স্ট্রিম তৈরি করার পছন্দের উপায়টি StringReader ক্লাসের মাধ্যমে ।

আপনি একটি তৈরি করতে পারেন java.io.Readerসঙ্গে java.io.StringReader, কিন্তু একটি গ্রহণ করার কোন অ্যাডাপ্টার হয় Readerএবং তৈরি InputStream

আমি একটি প্রাচীন বাগটি যথাযথ প্রতিস্থাপনের জন্য জিজ্ঞাসা করেছি, তবে এর মতো কোনও জিনিস নেই - যতদূর আমি বলতে পারি।

টোটাল-সুপারিশকৃত কার্যকার্যটি হ'ল java.lang.String.getBytes()ইনপুট হিসাবে এতে ব্যবহার করুন java.io.ByteArrayInputStream:

public InputStream createInputStream(String s, String charset)
    throws java.io.UnsupportedEncodingException {

    return new ByteArrayInputStream(s.getBytes(charset));
}

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

উত্তর:


78

আপডেট: এই উত্তরটি ওপি কী চায় না তা অবিকল is অন্যান্য উত্তর পড়ুন দয়া করে।

এই ক্ষেত্রে যখন আমরা মেমরিতে ডেটা পুনরায় রূপায়িত হওয়ার বিষয়ে চিন্তা করি না, দয়া করে ব্যবহার করুন:

new ByteArrayInputStream(str.getBytes("UTF-8"))

4
এই উত্তরের প্রস্তাবিত সমাধানটি প্রত্যাশিত, চিন্তা করা এবং প্রশ্ন দ্বারা প্রত্যাখ্যান করা হয়েছে। সুতরাং আমার মতে, এই উত্তরটি মুছে ফেলা উচিত।
মাইক নকিস

4
আপনি সঠিক হতে পারে। আমি মূলত এটি একটি মন্তব্য করেছিলাম সম্ভবত এটি কারণ ওপির প্রশ্নের আসল উত্তর ছিল না।
আন্দ্রেস রিওফ্রিও

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

10
Java7 হিসাবে:new ByteArrayInputStream(str.getBytes(StandardCharsets.UTF_8))
ধীরে ধীরে

19

আপনি যদি কমন্স-আইও প্যাকেজের উপর নির্ভরশীলতা মনে করেন না , তবে আপনি IOUtils.toInputStream (স্ট্রিং টেক্সট) পদ্ধতিটি ব্যবহার করতে পারেন ।


11
সেক্ষেত্রে আপনি এমন একটি নির্ভরতা যুক্ত করুন যা new নতুন বাইটআরআইপুট স্ট্রিম (ইনপুট.জেটবাইটস ()) ফিরিয়ে দেওয়া ছাড়া আর কিছুই করে না; এটি কি নির্ভরতার মূল্যবান? সমস্ত সততা, না - না।
whaefelinger

4
সত্য, এর পাশাপাশি এটি অপরিহার্যভাবে কাজ করে নিতে পারে না কারণ তিনি "স্ট্রিমটিকে মেমরিতে রূপায়িত করতে চান না" কারণ সিস্টেমের অন্য কোথাও স্ট্রিংকে মেকিরিজড করতে চেয়েছিলেন :)
ফোটিস প্যারাস্কেভোপল্লোস

আমাদের কাছে এমন কোনও গ্রন্থাগার রয়েছে যা কাস্টম অবজেক্টকে ইনপুট স্ট্রিমের উত্সে রূপান্তর করে; আইইউটিলস. টু ইনপুট স্ট্রিমের মতো কিছু (মাইবজেক্ট অবজেক্ট)?
নওয়াজিশ-স্ট্যাকওভারফ্লো

5

সেখানে এ্যাপাচি কমন্স-আই থেকে একটি অ্যাডাপ্টার যা InputStream, যা নামকরণ করা হয় পাঠক থেকে আত্তীকরণ হয় ReaderInputStream

উদাহরণ কোড:

@Test
public void testReaderInputStream() throws IOException {
    InputStream inputStream = new ReaderInputStream(new StringReader("largeString"), StandardCharsets.UTF_8);
    Assert.assertEquals("largeString", IOUtils.toString(inputStream, StandardCharsets.UTF_8));
}

তথ্যসূত্র: https://stackoverflow.com/a/27909221/5658642


3

আমার মনে হ'ল এটি করার সহজতম উপায় হ'ল কোন লেখকের মাধ্যমে ডেটা চাপানো:

public class StringEmitter {
  public static void main(String[] args) throws IOException {
    class DataHandler extends OutputStream {
      @Override
      public void write(final int b) throws IOException {
        write(new byte[] { (byte) b });
      }
      @Override
      public void write(byte[] b) throws IOException {
        write(b, 0, b.length);
      }
      @Override
      public void write(byte[] b, int off, int len)
          throws IOException {
        System.out.println("bytecount=" + len);
      }
    }

    StringBuilder sample = new StringBuilder();
    while (sample.length() < 100 * 1000) {
      sample.append("sample");
    }

    Writer writer = new OutputStreamWriter(
        new DataHandler(), "UTF-16");
    writer.write(sample.toString());
    writer.close();
  }
}

জেভিএম বাস্তবায়ন আমি 8K অংশগুলিতে পুশিত ডেটা ব্যবহার করছি তবে আপনি একবারে লেখা অক্ষরের সংখ্যা হ্রাস করে ফ্লাশ কল করে বাফার আকারে কিছুটা প্রভাব ফেলতে পারেন।


ডেটা এনকোড করার জন্য একজন রাইটার ব্যবহার করার জন্য আপনার নিজের চরসেটএনকডার র‌্যাপার লেখার বিকল্প, যদিও এটি সঠিকভাবে করা ব্যথার কিছু। এটি একটি নির্ভরযোগ্য (অকার্যকর হলে) বাস্তবায়ন হওয়া উচিত:

/** Inefficient string stream implementation */
public class StringInputStream extends InputStream {

  /* # of characters to buffer - must be >=2 to handle surrogate pairs */
  private static final int CHAR_CAP = 8;

  private final Queue<Byte> buffer = new LinkedList<Byte>();
  private final Writer encoder;
  private final String data;
  private int index;

  public StringInputStream(String sequence, Charset charset) {
    data = sequence;
    encoder = new OutputStreamWriter(
        new OutputStreamBuffer(), charset);
  }

  private int buffer() throws IOException {
    if (index >= data.length()) {
      return -1;
    }
    int rlen = index + CHAR_CAP;
    if (rlen > data.length()) {
      rlen = data.length();
    }
    for (; index < rlen; index++) {
      char ch = data.charAt(index);
      encoder.append(ch);
      // ensure data enters buffer
      encoder.flush();
    }
    if (index >= data.length()) {
      encoder.close();
    }
    return buffer.size();
  }

  @Override
  public int read() throws IOException {
    if (buffer.size() == 0) {
      int r = buffer();
      if (r == -1) {
        return -1;
      }
    }
    return 0xFF & buffer.remove();
  }

  private class OutputStreamBuffer extends OutputStream {

    @Override
    public void write(int i) throws IOException {
      byte b = (byte) i;
      buffer.add(b);
    }

  }

}

2

ভাল, একটি সম্ভাব্য উপায় হ'ল:

  • একটা তৈরি কর PipedOutputStream
  • এটি পাইপ PipedInputStream
  • একটি OutputStreamWriterচারপাশে মোড়ানো PipedOutputStream(আপনি কনস্ট্রাক্টরের মধ্যে এনকোডিং নির্দিষ্ট করতে পারেন)
  • এছাড়াও, আপনি যা লিখতে OutputStreamWriterপারেন তা থেকে পড়তে পারেন PipedInputStream!

অবশ্যই এটি এটি করার মতো বরং হ্যাকিশ উপায় বলে মনে হচ্ছে তবে অন্তত এটি একটি উপায়।


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

5
পাইপড (ইনপুট | আউটপুট) স্ট্রিম সম্পর্কে আপনাকে সতর্ক থাকতে হবে। দস্তাবেজ অনুসারে: "... একক থ্রেড থেকে উভয় বস্তু ব্যবহার করার চেষ্টা করা বাঞ্ছনীয় নয়, কারণ এটি থ্রেডটিকে
ব্রায়ান কাইল

1

একটি সমাধান আপনার নিজের রোল, একটি তৈরি হয় InputStreamবাস্তবায়ন যে সম্ভবত ব্যবহার করেন java.nio.charset.CharsetEncoderপ্রতিটি সঙ্কেতাক্ষরে লিখা charবা খণ্ড charজন্য বাইটের একটি অ্যারের গুলি InputStreamপ্রয়োজনীয় হিসাবে।


4
একবারে একটি চরিত্র জিনিস করা ব্যয়বহুল। এ কারণেই আমাদের ইনপুটস্ট্রিমের মতো "ছিটিয়ে থাকা পুনরাবৃত্তকারী" রয়েছে যা আমাদের একবারে বাফার পড়তে দেয়।
টম হাটিন -

আমি টমের সাথে একমত - আপনি সত্যিই একবারে এই চরিত্রটি করতে চান না।
এডি 1

4
যদি না ডেটা সত্যিই ছোট হয় এবং অন্যান্য জিনিস (উদাহরণস্বরূপ নেটওয়ার্ক ল্যাটেন্সি) বেশি সময় নেয়। তাহলে তাতে কিছু যায় আসে না। :)
আন্দ্রেস রিওফ্রিও

0

আপনি org.hsqldb.lib লাইব্রেরির সাহায্য নিতে পারেন।

public StringInputStream(String paramString)
  {
    this.str = paramString;
    this.available = (paramString.length() * 2);
  }

4
সাধারণত, প্রশ্নগুলি আরও কার্যকর হয় যদি তারা কোডটি কী করতে চায় তার একটি ব্যাখ্যা অন্তর্ভুক্ত করে।
পিটার

-1

আমি জানি এটি একটি পুরানো প্রশ্ন তবে আমার নিজেরও আজ একই সমস্যা ছিল এবং এটি আমার সমাধান ছিল:

public static InputStream getStream(final CharSequence charSequence) {
 return new InputStream() {
  int index = 0;
  int length = charSequence.length();
  @Override public int read() throws IOException {
   return index>=length ? -1 : charSequence.charAt(index++);
  }
 };
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.