আমি কীভাবে কোনও ফাইলের বিষয়বস্তু থেকে জাভা স্ট্রিং তৈরি করব?


1512

আমি কিছু সময়ের জন্য নীচের আইডিয়ামটি ব্যবহার করছি। কমপক্ষে আমি যে সাইটগুলিতে গিয়েছি সেখানে এটি সর্বাধিক বিস্তৃত বলে মনে হচ্ছে।

জাভাতে কোনও স্ট্রিংয়ে কোনও ফাইল পড়ার জন্য আরও ভাল / আলাদা উপায় আছে কি?

private String readFile(String file) throws IOException {
    BufferedReader reader = new BufferedReader(new FileReader (file));
    String         line = null;
    StringBuilder  stringBuilder = new StringBuilder();
    String         ls = System.getProperty("line.separator");

    try {
        while((line = reader.readLine()) != null) {
            stringBuilder.append(line);
            stringBuilder.append(ls);
        }

        return stringBuilder.toString();
    } finally {
        reader.close();
    }
}

7
এনআইও-র সাথে কী খুব সহজ পদ্ধতিতে কেউ আমাকে ব্যাখ্যা করতে পারেন? প্রতিবার আমি এটির বিষয়ে পড়ি আমি চ্যানেলের নবম উল্লেখে হারিয়ে
যাব

7
মনে রাখবেন যে এটির নিশ্চয়তা নেই যে ফাইলের লাইন বিভাজকটি সিস্টেমের লাইন বিভাজকের মতো নয়।
হেনরিক পল

138
আপনি কি দয়া করে একটি যথাযথ চেষ্টা সন্নিবেশ করিয়ে দিতে পারেন যা পাঠককে বন্ধ করে দেয়? কেউ হয়ত এই উদাহরণটি ব্যবহার করতে পারেন এবং তার কোডে একটি বাগ প্রবর্তন করতে পারেন।
হ্যান্স-পিটার স্টার

6
উপরের কোডটিতে শেষ লাইনে অতিরিক্ত নতুন লাইন চর যুক্ত করার একটি বাগ রয়েছে। এটি অনুসরণ করার মতো কিছু হওয়া উচিত (লাইন = রিডার .ডলাইন ())! = নাল) {স্ট্রিংবিল্ডার.অ্যাপেন্ড (লাইন); } যখন (লাইন = রিডার.রেডলাইন ())! = নাল) {স্ট্রিংবিল্ডার.অ্যাপেন্ড (এলএস); স্ট্রিংবিল্ডার.এপেন্ড (লাইন); }
গভীর

27
জাভা 7 byte[] Files.readAllBytes(file);তাদের সাথে পরিচয় করিয়ে দিয়েছে , যারা 'এক-লাইন' স্ক্যানার সমাধানের পরামর্শ দেয়: আপনার কি এটি বন্ধ করার দরকার নেই?
Val,

উত্তর:


1532

একটি ফাইল থেকে সমস্ত পাঠ পড়ুন

জাভা 11 লাইন টার্মিনেটর সংরক্ষণ করে ছোট ফাইলগুলি পড়ার জন্য রিডস্ট্রিং () পদ্ধতি যুক্ত করেছে String:

String content = Files.readString(path, StandardCharsets.US_ASCII);

জাভা 7 এবং 11 এর মধ্যে সংস্করণগুলির জন্য, এখানে একটি কমপ্যাক্ট, দৃ rob় প্রতিমা, একটি ইউটিলিটি পদ্ধতিতে আবৃত:

static String readFile(String path, Charset encoding) 
  throws IOException 
{
  byte[] encoded = Files.readAllBytes(Paths.get(path));
  return new String(encoded, encoding);
}

একটি ফাইল থেকে পাঠ্য লাইন পড়ুন

জাভা 7 কোনও ফাইলকে পাঠ্যের রেখাগুলি হিসাবে পড়ার জন্য একটি সুবিধার পদ্ধতি যুক্ত করেছে , যা হিসাবে উপস্থাপন করা হয়েছে List<String>। এই পদ্ধতিরটি "ক্ষয়ক্ষতিযুক্ত" কারণ প্রতিটি লাইনের শেষ থেকে লাইন বিভাজকগুলি কেটে ফেলা হয়।

List<String> lines = Files.readAllLines(Paths.get(path), encoding);

জাভা 8 Files.lines()একটি উত্পাদনের পদ্ধতি যুক্ত করেছে Stream<String>। আবার, এই পদ্ধতিটি ক্ষতিকারক কারণ লাইন বিভাজকগুলি ছিনিয়ে নেওয়া হয়েছে। IOExceptionফাইলটি পড়ার সময় যদি কোনও সমস্যার মুখোমুখি হয় তবে এটি একটি মুড়ে ফেলা হয় UncheckedIOException, যেহেতু Streamল্যাম্বডাস গ্রহণ করে না যা পরীক্ষিত ব্যতিক্রমগুলি ফেলে দেয়।

try (Stream<String> lines = Files.lines(path, encoding)) {
  lines.forEach(System.out::println);
}

এটির জন্য Streamএকটি close()কল প্রয়োজন ; এটি এপিআই তে দুর্বল নথিভুক্ত, এবং আমার সন্দেহ হয় যে অনেক লোকের এমনকি Streamএকটি close()পদ্ধতি রয়েছে তা খেয়াল করেন না । প্রদর্শিত হিসাবে একটি এআরএম-ব্লক ব্যবহার নিশ্চিত করুন।

আপনি যদি কোনও ফাইল ব্যতীত অন্য কোনও উত্সের সাথে কাজ করছেন তবে আপনি তার পরিবর্তে lines()পদ্ধতিটি ব্যবহার করতে পারেন BufferedReader

স্মৃতি ব্যবহার

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

দ্বিতীয় পদ্ধতি, পংক্তিগুলি পড়ার জন্য সাধারণত আরও মেমরি দক্ষ হয়, কারণ ডিকোডিংয়ের জন্য ইনপুট বাইট বাফারটি পুরো ফাইলটি ধারণ করে না। তবে এটি এখনও উপলব্ধ ফাইলগুলির জন্য উপযুক্ত নয় যেগুলি উপলব্ধ মেমরির তুলনায় খুব বড় not

বড় ফাইলগুলি পড়ার জন্য আপনার প্রোগ্রামের জন্য আপনার আলাদা ডিজাইন দরকার, একটি যা একটি স্ট্রিম থেকে কিছু অংশ পাঠ করে, এটি প্রক্রিয়া করে এবং তারপরে একই স্থির আকারের মেমরি ব্লকটি পুনরায় ব্যবহার করে পরবর্তীটিতে চলে যায়। এখানে, "বৃহত্তর" কম্পিউটারের চশমার উপর নির্ভর করে। আজকাল, এই প্রান্তিকতা র‍্যামের অনেকগুলি গিগাবাইট হতে পারে। তৃতীয় পদ্ধতিটি Stream<String>হ'ল এটি ব্যবহার করার একটি উপায় হ'ল যদি আপনার ইনপুট "রেকর্ডগুলি" স্বতন্ত্র লাইন হয়। (এর readLine()পদ্ধতিটি ব্যবহার BufferedReaderকরা এই পদ্ধতির সমতুল্য।

অক্ষর এনকোডিং

মূল পোস্টে নমুনা থেকে হারিয়ে যাওয়া একটি জিনিস হ'ল অক্ষর এনকোডিং। কিছু বিশেষ কেস রয়েছে যেখানে প্ল্যাটফর্মের ডিফল্টটি আপনি যা চান তা হ'ল তবে সেগুলি বিরল এবং আপনার পছন্দটিকে ন্যায়সঙ্গত করতে সক্ষম হওয়া উচিত।

StandardCharsetsবর্গ সমস্ত Java রানটাইম প্রয়োজনীয় এনকোডিং জন্য কিছু ধ্রুবক সংজ্ঞায়িত:

String content = readFile("test.txt", StandardCharsets.UTF_8);

প্ল্যাটফর্ম ডিফল্ট থেকে পাওয়া যায় বর্গ নিজেই:Charset

String content = readFile("test.txt", Charset.defaultCharset());

দ্রষ্টব্য: এই উত্তরটি আমার জাভা 6 সংস্করণটি মূলত প্রতিস্থাপন করে। জাভা 7 এর ইউটিলিটি কোডটি নিরাপদে সরল করে, এবং পুরানো উত্তর, যা ম্যাপযুক্ত বাইট বাফার ব্যবহার করেছিল, ম্যাপযুক্ত বাফার আবর্জনা সংগ্রহ না করা অবধি ফাইলটি মুছে ফেলা থেকে বিরত ছিল। আপনি এই উত্তরের "সম্পাদিত" লিঙ্কের মাধ্যমে পুরানো সংস্করণটি দেখতে পারেন।


3
প্রযুক্তিগতভাবে বলতে গেলে, এটি সময় এবং স্থানের (ও) এন। গুণগতভাবে, স্ট্রিংসের অপরিবর্তনীয়তার প্রয়োজনীয়তার কারণে এটি মেমরির পক্ষে বেশ শক্ত; অস্থায়ীভাবে মেমরিতে চর ডেটার দুটি কপি রয়েছে, ততক্ষণ এনকোডড বাইটের জন্য ঘর। কিছু একক-বাইট এনকোডিং ধরে নিলে এটির (অস্থায়ীভাবে) ফাইলের প্রতিটি অক্ষরের জন্য 5 বাইট মেমরির প্রয়োজন হবে। যেহেতু প্রশ্নটি একটি স্ট্রিংয়ের জন্য বিশেষত জিজ্ঞাসা করে, আমি এটিই দেখাই তবে আপনি যদি "ডিকোড" দ্বারা ফিরে আসা চারবফারের সাথে কাজ করতে পারেন তবে মেমরির প্রয়োজনীয়তা অনেক কম। সময় অনুসারে, আমি মনে করি না আপনি মূল জাভা লিবগুলিতে খুব দ্রুত কিছু খুঁজে পাবেন।
এরিকসন

5
সম্ভাব্য টাইপো? এনআইওর একটি jars.nio.charset.Charset নামে একটি চারসেট (চারসেট নয়) শ্রেণি রয়েছে। চারসেট কি এমন হওয়া উচিত ছিল?
জোনাথন রাইট

31
দ্রষ্টব্য: কিছুটা কোড ব্যায়াম করার পরে আমি জানতে পেরেছিলাম যে আপনি এই পদ্ধতিটি পড়ার পরে সঠিকভাবে ফাইলটি নির্ভরযোগ্যভাবে মুছতে পারবেন না, এটি কোনও ক্ষেত্রে নন ইস্যু হতে পারে, তবে আমার নয়। এটি কি এই ইস্যুটির সাথে সম্পর্কযুক্ত হতে পারে: বাগসসন.বুনড্যাটাবেস / ভিউ_বাগ.ডো ? বুগ_আইডি=4715154 ? অবশেষে আমি জন স্কিটির প্রস্তাব নিয়ে গিয়েছিলাম যা এই বাগ থেকে ভোগেনা। যাইহোক, আমি কেবল অন্য ক্ষেত্রে, কেবলমাত্র তথ্যটিই দিতে চেয়েছিলাম ...
সাবাস্তিয়ান নসবাউমার

5
@ সাবাসতিয়েন নসবাউমার: আমিও এই সমস্যাটি ঘটিয়েছি। বিস্ময়কর যে বাগটি "উইল ফিক্স" হিসাবে চিহ্নিত করা হয়েছে। এর মূলত অর্থ FileChannel#mapহ'ল সাধারণভাবে অপব্যবহারযোগ্য।
জুনাস পুলক্কা

4
@ সাবাসতিয়েন নসবাউমার: ওরাকল / সান বাগ ডাটাবেস থেকে বাগটি মুছে ফেলা হয়েছে: "এই বাগটি উপলভ্য নয়।" গুগল ওয়েবসাইটটি ওয়েবক্যাসে
q=

350

আপনি যদি কোনও বাহ্যিক গ্রন্থাগার ব্যবহার করতে ইচ্ছুক হন তবে অ্যাপাচি কমন্স আইও (200 কেবি জেআর) দেখুন। এটি একটি রয়েছে org.apache.commons.io.FileUtils.readFileToString()পদ্ধতি যা আপনি একটি সম্পূর্ণ পড়ার অনুমতি দেয় Fileএকটি মধ্যে Stringকোডের এক লাইন সঙ্গে।

উদাহরণ:

import java.io.*;
import java.nio.charset.*;
import org.apache.commons.io.*;

public String readFile() throws IOException {
    File file = new File("data.txt");
    return FileUtils.readFileToString(file, StandardCharsets.UTF_8);
}

আপনার সরবরাহ করা ইউআরএলটিতে আমি সেই পদ্ধতিটি পাই না।
অস্কাররাইজ

2
এটি org.apache.commons.io.FileUtils শ্রেণিতে
কা

2
আমি ফাইল ইউটিলেটগুলিও ব্যবহার করছি, তবে আমি ভাবছি যে ফাইলUtils বা স্বীকৃত নিও উত্তর ব্যবহার করে বেটউইউইন এর চেয়ে ভাল কী?
গিলিয়াম

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

183

এর উপর ভিত্তি করে একটি খুব পাতলা সমাধান Scanner:

Scanner scanner = new Scanner( new File("poem.txt") );
String text = scanner.useDelimiter("\\A").next();
scanner.close(); // Put this call in a finally block

অথবা, আপনি যদি চরসেটটি সেট করতে চান:

Scanner scanner = new Scanner( new File("poem.txt"), "UTF-8" );
String text = scanner.useDelimiter("\\A").next();
scanner.close(); // Put this call in a finally block

অথবা, একটি রিসোর্স- ব্লক সহ-রিসোর্স ব্লক সহ, যা আপনাকে কল scanner.close()করবে:

try (Scanner scanner = new Scanner( new File("poem.txt"), "UTF-8" )) {
    String text = scanner.useDelimiter("\\A").next();
}

মনে রাখবেন যে Scannerকনস্ট্রাক্টর একটি নিক্ষেপ করতে পারে IOException। এবং আমদানি করতে ভুলবেন না java.ioএবং java.util

সূত্র: প্যাট নিমেরির ব্লগ


4
\\ একটি কাজ করে কারণ সেখানে "ফাইলের অন্য কোনও সূচনা" নেই, তাই আপনি আসলে শেষ টোকেনটি পড়েন ... এটিও প্রথম। \\ Z দিয়ে কখনই চেষ্টা করবেন না। এছাড়াও নোট করুন যে আপনি ফাইল, ইনপুট স্ট্রিম, চ্যানেলগুলির মতো পঠনযোগ্য যা কিছু পড়তে পারেন ... আমি কখনও কখনও এই কোডটি গ্রহনের প্রদর্শন উইন্ডো থেকে পড়তে ব্যবহার করি, যখন আমি নিশ্চিত না যে আমি কোনও ফাইল বা অন্য পড়ছি কিনা .. .হায়, ক্লাসপাথ আমাকে বিভ্রান্ত করে।
পাবলো গ্রিসাফি

1
পোস্টার হিসাবে, আমি বলতে পারি যে ফাইলটি সঠিকভাবে কাছে থাকলে এবং আমি কখনই জানি না ... আমি প্রযোজনা কোডে এটি কখনই লিখি না, আমি এটি কেবল পরীক্ষাগুলি বা ডিবাগের জন্যই ব্যবহার করি।
পাবলো গ্রিসাফি

2
আমার মনে হয়
এটির

20
স্ক্যানার ক্লোজযোগ্য প্রয়োগ করে (এটি উত্সটির নিকটবর্তী হওয়ার আহ্বান জানায়) - তাই মার্জিত থাকাকালীন এটি সত্যই ওয়ান-লাইনার হওয়া উচিত নয়। বাফারের ডিফল্ট আকার 1024, তবে স্ক্যানার প্রয়োজনীয় আকারটি বাড়িয়ে তুলবে (স্ক্যানার # মেকস্পেস (দেখুন)
ইরাক্যাম

8
এটির সাথে খালি ফাইলগুলির জন্য ব্যর্থ java.util.NoSuchElementException
স্পেসট্রকার

116
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;

String content = new String(Files.readAllBytes(Paths.get("readMe.txt")), StandardCharsets.UTF_8);

জাভা 7 যেহেতু আপনি এইভাবে এটি করতে পারেন।


এটি উত্তর হিসাবে একক লাইন, কোনও বাহ্যিক libs হিসাবে গ্রহণ করা উচিত।
চেরি

এটি ফাইলটিতে উপস্থিত না থাকলেও এটি শেষে একটি নতুন লাইনের চরিত্র যুক্ত করেছে
স্টেফান হাবেল

79

যদি আপনি এমন কোনও বিকল্প সন্ধান করছেন যা কোনও তৃতীয় পক্ষের লাইব্রেরির সাথে জড়িত না (যেমন কমন্স আই / ও ), আপনি স্ক্যানার শ্রেণিটি ব্যবহার করতে পারেন :

private String readFile(String pathname) throws IOException {

    File file = new File(pathname);
    StringBuilder fileContents = new StringBuilder((int)file.length());        

    try (Scanner scanner = new Scanner(file)) {
        while(scanner.hasNextLine()) {
            fileContents.append(scanner.nextLine() + System.lineSeparator());
        }
        return fileContents.toString();
    }
}

2
আমি মনে করি এটি সেরা উপায়। পরীক্ষা করে দেখুন java.sun.com/docs/books/tutorial/essential/io/scanning.html
Tarski

3
স্ট্রিং গ্রহণকারী স্ক্যানার কনস্ট্রাক্টর স্ট্রিংটি পড়ার জন্য কোনও ফাইলের নাম হিসাবে বিবেচনা করে না, তবে স্ক্যান করা পাঠ্য হিসাবে বিবেচনা করে। আমি সব সময় ভুল করি। : - /
অ্যালান মুর

অ্যালান, ভাল ক্যাচ আমি ঠিক করার জন্য ডনের উত্তরটি সামান্য সম্পাদনা করেছি (আশা করি)।
জোনিক

3
fileContents.append (scanner.nextLine ()) পরিশেষে যোগ (lineSeparator)।
-13

1
সূচনা বিবরণীতে পরিবর্তন করুন Scanner scanner = new Scanner((Readable) new BufferedReader(new FileReader(file)));। অন্যথায় আপনি কেবল ফাইলের কিছু অংশ ক্যাপচার করতে পারেন।
ওয়েই ইয়াং

71

কম্বল আইইউটিলেসের মতো পেয়ারাতে একটি পদ্ধতি রয়েছে যা উইল আউস রোহর উল্লেখ করেছেন:

import com.google.common.base.Charsets;
import com.google.common.io.Files;

// ...

String text = Files.toString(new File(path), Charsets.UTF_8);

পিগিপিগলেট দ্বারা সম্পাদনা হ্রাস
Files#toString করা হয়েছে এবং অক্টোবোর 2019 অপসারণের কারণে। পরিবর্তে ব্যবহার করুন Files.asCharSource(new File(path), StandardCharsets.UTF_8).read();

অস্কার রেয়েসের সম্পাদনা

এটি উদ্ধৃত লাইব্রেরির অন্তর্নিহিত কোড (সরলীকৃত):

InputStream in = new FileInputStream(file);
byte[] b  = new byte[file.length()];
int len = b.length;
int total = 0;

while (total < len) {
  int result = in.read(b, total, len - total);
  if (result == -1) {
    break;
  }
  total += result;
}

return new String( b , Charsets.UTF_8 );

সম্পাদনা (জোনিক দ্বারা): উপরের সাম্প্রতিক পেয়ারা সংস্করণগুলির উত্স কোডটির সাথে মেলে না। বর্তমান উৎসের জন্য, ক্লাস দেখতে ফাইল , CharStreams , ByteSource এবং CharSource মধ্যে com.google.common.io প্যাকেজ।


এই কোডটি দীর্ঘ থেকে আন্তঃ পর্যন্ত castালাই করছে যা বড় ফাইলগুলির সাথে কিছু উন্মাদ আচরণ পপ আপ করতে পারে। অতিরিক্ত স্থান আছে এবং আপনি ইনপুটস্ট্রিমটি কোথায় বন্ধ করবেন?
মোহাম্মদ তাহের আলরেফেই

@MTA: প্রবাহ হয় বন্ধ, নোট ব্যবহার Closerমধ্যে CharSource । উত্তরের কোডটি আসল, বর্তমান পেয়ারা উত্স নয়।
জোনিক

54
import java.nio.file.Files;

.......

 String readFile(String filename) {
            File f = new File(filename);
            try {
                byte[] bytes = Files.readAllBytes(f.toPath());
                return new String(bytes,"UTF-8");
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return "";
    }

6
বা আরও সহজ:new String(Files.readAllBytes(FileSystems.getDefault().getPath( filename)));

12
বা new String(Files.readAllBytes(Paths.get(filename)));:-)
Assafmo

1
ভাল খেলেছে, এবং Pathsগুগলিংয়ের পরবর্তী লোকটিকে বাঁচানোর জন্য স্পষ্টতই 1.7+ রয়েছে FileSystems। (এটি
ডাঙ

4
এটি লজ্জাজনক এই উত্তরটির বেশি ভোট নেই। আমি একটি স্ট্রিংয়ে একটি টেক্সট ফাইল পাওয়ার দ্রুত এবং সহজতম উপায়টির সন্ধান করছিলাম। এটি এটি এবং যদি আমি নীচে এবং নীচে এবং নীচে স্ক্রোল না করি তবে আমি এটি মিস করতাম। ওপিকে এই উত্তরটি শীর্ষে নিয়ে যাওয়ার জন্য গ্রহণ করার কথা বিবেচনা করা উচিত।
কাঁটা

@ উত্তর এই উত্তরটিতে ভয়াবহ ত্রুটি পরিচালনার কাজ রয়েছে। উত্পাদন কোডে এই পদ্ধতিটি ব্যবহার করবেন না বা আরও ভাল: কখনই নয়।
xehpuk

51

আপনার যদি স্ট্রিং প্রসেসিং প্রয়োজন হয় (সমান্তরাল প্রক্রিয়াকরণ) জাভা 8 এর দুর্দান্ত স্ট্রিম এপিআই রয়েছে।

String result = Files.lines(Paths.get("file.txt"))
                    .parallel() // for parallel processing 
                    .map(String::trim) // to change line   
                    .filter(line -> line.length() > 2) // to filter some lines by a predicate                        
                    .collect(Collectors.joining()); // to join lines

আরও উদাহরণ জেডিকে নমুনায় পাওয়া যায় sample/lambda/BulkDataOperationsযা ওরাকল জাভা এসই 8 ডাউনলোড পৃষ্ঠা থেকে ডাউনলোড করা যায়

অন্য একটি লাইন উদাহরণ

String out = String.join("\n", Files.readAllLines(Paths.get("file.txt")));

লাইনগুলি পড়ার পরে বা তার আগে। সমান্তরাল () কি ঘটে?
ইস্তান

টার্মিনাল অপারেশন সংগ্রহ (...) শুরু হওয়ার পরে আসল কাজ শুরু হয়। স্ট্রিম অলসভাবে জনবহুল লাইন লাইন। প্রক্রিয়া করার আগে পুরো ফাইলটি মেমোরিতে পড়ার দরকার নেই (যেমন ফিল্টারিং এবং ম্যাপিং)।
Andrei N

খালি খালি লাইনগুলি বেছে নেওয়ার আগে ট্রিম করবেন?
থোরবজর্ন রাভন অ্যান্ডারসন

50

এই কোডটি লাইন বিরতিগুলিকে স্বাভাবিক করবে, যা আপনি যা করতে চান তা হতে পারে বা নাও পারে।

এখানে এমন বিকল্প রয়েছে যা এটি না করে এবং এনআইও কোডের তুলনায় (আইএমও) আরও সহজ (যদিও এটি এখনও ব্যবহার করে java.nio.charset.Charset):

public static String readFile(String file, String csName)
            throws IOException {
    Charset cs = Charset.forName(csName);
    return readFile(file, cs);
}

public static String readFile(String file, Charset cs)
            throws IOException {
    // No real need to close the BufferedReader/InputStreamReader
    // as they're only wrapping the stream
    FileInputStream stream = new FileInputStream(file);
    try {
        Reader reader = new BufferedReader(new InputStreamReader(stream, cs));
        StringBuilder builder = new StringBuilder();
        char[] buffer = new char[8192];
        int read;
        while ((read = reader.read(buffer, 0, buffer.length)) > 0) {
            builder.append(buffer, 0, read);
        }
        return builder.toString();
    } finally {
        // Potential issue here: if this throws an IOException,
        // it will mask any others. Normally I'd use a utility
        // method which would log exceptions and swallow them
        stream.close();
    }        
}

1
এই পুরানো মন্তব্যটি পুনরুদ্ধারের জন্য আমাকে ক্ষমা করুন, তবে আপনি কি "ফাইল" নামক একটি স্ট্রিং অবজেক্টে পাস করার অর্থ দিয়েছিলেন বা তার পরিবর্তে কোনও ফাইল অবজেক্ট হওয়া উচিত?
ব্রায়ান লারসন

28

ডিস্ক বা নেটওয়ার্ক থেকে স্ট্রিং হিসাবে ফাইলটি পড়ার সম্ভাব্য সমস্ত উপায়ে সংগ্রহ করেছেন।

  • পেয়ারা: গুগল ক্লাস ব্যবহার করে Resources,Files

    static Charset charset = com.google.common.base.Charsets.UTF_8;
    public static String guava_ServerFile( URL url ) throws IOException {
        return Resources.toString( url, charset );
    }
    public static String guava_DiskFile( File file ) throws IOException {
        return Files.toString( file, charset );
    }

  • আপাচে - আইওউটিস, ফাইল ইউটিস ক্লাস ব্যবহার করে কমন্স আইও

    static Charset encoding = org.apache.commons.io.Charsets.UTF_8;
    public static String commons_IOUtils( URL url ) throws IOException {
        java.io.InputStream in = url.openStream();
        try {
            return IOUtils.toString( in, encoding );
        } finally {
            IOUtils.closeQuietly(in);
        }
    }
    public static String commons_FileUtils( File file ) throws IOException {
        return FileUtils.readFileToString( file, encoding );
        /*List<String> lines = FileUtils.readLines( fileName, encoding );
        return lines.stream().collect( Collectors.joining("\n") );*/
    }

  • স্ট্রিম API ব্যবহার করে জাভা 8 বাফাররিডার

    public static String streamURL_Buffer( URL url ) throws IOException {
        java.io.InputStream source = url.openStream();
        BufferedReader reader = new BufferedReader( new InputStreamReader( source ) );
        //List<String> lines = reader.lines().collect( Collectors.toList() );
        return reader.lines().collect( Collectors.joining( System.lineSeparator() ) );
    }
    public static String streamFile_Buffer( File file ) throws IOException {
        BufferedReader reader = new BufferedReader( new FileReader( file ) );
        return reader.lines().collect(Collectors.joining(System.lineSeparator()));
    }

  • রেগেক্স সহ স্ক্যানার ক্লাস \A। যা ইনপুট শুরুর সাথে মেলে।

    static String charsetName = java.nio.charset.StandardCharsets.UTF_8.toString();
    public static String streamURL_Scanner( URL url ) throws IOException {
        java.io.InputStream source = url.openStream();
        Scanner scanner = new Scanner(source, charsetName).useDelimiter("\\A");
        return scanner.hasNext() ? scanner.next() : "";
    }
    public static String streamFile_Scanner( File file ) throws IOException {
        Scanner scanner = new Scanner(file, charsetName).useDelimiter("\\A");
        return scanner.hasNext() ? scanner.next() : "";
    }

  • জাভা 7 ( java.nio.file.Files.readAllBytes)

    public static String getDiskFile_Java7( File file ) throws IOException {
        byte[] readAllBytes = java.nio.file.Files.readAllBytes(Paths.get( file.getAbsolutePath() ));
        return new String( readAllBytes );
    }

  • BufferedReaderব্যবহার InputStreamReader

    public static String getDiskFile_Lines( File file ) throws IOException {
        StringBuffer text = new StringBuffer();
        FileInputStream fileStream = new FileInputStream( file );
        BufferedReader br = new BufferedReader( new InputStreamReader( fileStream ) );
        for ( String line; (line = br.readLine()) != null; )
            text.append( line + System.lineSeparator() );
        return text.toString();
    }

উপরোক্ত পদ্ধতিগুলি অ্যাক্সেস করার জন্য মূল পদ্ধতির উদাহরণ।

public static void main(String[] args) throws IOException {
    String fileName = "E:/parametarisation.csv";
    File file = new File( fileName );

    String fileStream = commons_FileUtils( file );
            // guava_DiskFile( file );
            // streamFile_Buffer( file );
            // getDiskFile_Java7( file );
            // getDiskFile_Lines( file );
    System.out.println( " File Over Disk : \n"+ fileStream );


    try {
        String src = "https://code.jquery.com/jquery-3.2.1.js";
        URL url = new URL( src );

        String urlStream = commons_IOUtils( url );
                // guava_ServerFile( url );
                // streamURL_Scanner( url );
                // streamURL_Buffer( url );
        System.out.println( " File Over Network : \n"+ urlStream );
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }
}

@দেখা


26

যদি এটি কোনও পাঠ্য ফাইল থাকে তবে কেন আপনি অ্যাপাচি কমন্স-আইও ব্যবহার করবেন না ?

এটির নিম্নলিখিত পদ্ধতি রয়েছে

public static String readFileToString(File file) throws IOException

আপনি চাইলে লাইনগুলি তালিকা হিসাবে ব্যবহার করুন

public static List<String> readLines(File file) throws IOException

25

জেডিকে ১১:

String file = ...
Path path = Paths.get(file);
String content = Files.readString(path);
// Or readString(path, someCharset), if you need a Charset different from UTF-8

কেন, ওহ কেন, নতুন পদ্ধতিগুলি চালু করুন যা 2018 সালে ডিফল্ট চরসেটের উপর নির্ভর করে?
mryan

2
@ এম্রিয়ান এই পদ্ধতিটি ডিফল্ট সিস্টেম চরসেটের উপর নির্ভর করে না। এটি ইউটিএফ -8 এর ডিফল্ট, এটি ঠিক আছে।
লেভেন্টভ

@ লেভেন্টভ আপনি ঠিক বলেছেন! ফাইলস.আরেডলাইনগুলিও তাই! যা ফাইলগুলিকে এপিআই পুরানো পদ্ধতির সাথে খুব সামঞ্জস্যপূর্ণ করে তোলে না তবে এটি আরও ভাল জন্য :)
mryan

17

কোনও ফাইল বাইনারি হিসাবে পড়তে এবং শেষে রূপান্তর করতে

public static String readFileAsString(String filePath) throws IOException {
    DataInputStream dis = new DataInputStream(new FileInputStream(filePath));
    try {
        long len = new File(filePath).length();
        if (len > Integer.MAX_VALUE) throw new IOException("File "+filePath+" too large, was "+len+" bytes.");
        byte[] bytes = new byte[(int) len];
        dis.readFully(bytes);
        return new String(bytes, "UTF-8");
    } finally {
        dis.close();
    }
}

16

জাভা 7 এর সাথে, কোনও ইউটিএফ -8 ফাইলটি পড়ার জন্য এটি আমার পছন্দসই বিকল্প:

String content = new String(Files.readAllBytes(Paths.get(filename)), "UTF-8");

জাভা 7 এর পরে, জেডিকে নতুন java.nio.fileএপিআই রয়েছে, যা অনেকগুলি শর্টকাট সরবরাহ করে, তাই 3 য় পক্ষের লাইব্রেরি সবসময় সাধারণ ফাইল অপারেশনের জন্য প্রয়োজন হয় না।


15

জাভা তার সমস্ত ক্ষেত্রে অত্যন্ত সাধারণ এবং নমনীয় হওয়ার চেষ্টা করে। ফলস্বরূপ, স্ক্রিপ্টিং ভাষায় তুলনামূলকভাবে সহজ কিছু (আপনার কোডটি open(file).read()পাইথনের " " দিয়ে প্রতিস্থাপন করা হবে ) অনেক জটিল। বাহ্যিক গ্রন্থাগার ( উইল আউস রোহর যেমন উল্লেখ করেছেন) ব্যবহার করা ছাড়া এটি করার কোনও ছোট উপায় বলে মনে হয় না । আপনার বিকল্পগুলি:

  • একটি বাহ্যিক গ্রন্থাগার ব্যবহার করুন।
  • আপনার সমস্ত প্রকল্পে এই কোডটি অনুলিপি করুন।
  • আপনার নিজস্ব মিনি-গ্রন্থাগার তৈরি করুন যাতে আপনি প্রায়শই ব্যবহার করেন এমন ফাংশন থাকে।

আপনার সেরা বাজি সম্ভবত দ্বিতীয়টি, কারণ এটির মধ্যে সর্বনিম্ন নির্ভরতা রয়েছে।


4
Yeap। এটি "উচ্চ" স্তরের ভাষাটিকে আলাদা অর্থ দেয় meaning জাভা সি এর সাথে তুলনামূলকভাবে উচ্চ স্তরের তবে পাইথন বা রুবির সাথে তুলনামূলক কম
অস্কাররেজ

3
সম্মত হন যে জাভা উচ্চ-স্তরের বিমূর্ততায় দীর্ঘ তবে সুবিধা পদ্ধতিতে সংক্ষিপ্ত
ডোনাল

3
সত্য, জাভা ফাইলগুলির সাথে ডিল করার অনেকগুলি পাগল রয়েছে এবং তাদের মধ্যে অনেকগুলি জটিল বলে মনে হচ্ছে। তবে এটি উচ্চ স্তরের ভাষাগুলিতে আমাদের কাছে যা আছে তার কাছাকাছি:byte[] bytes = Files.readAllBytes(someFile.toPath());
কাঁটা

11

8 বা ততোধিক জেডিকে ব্যবহার করা:

কোনও বাহ্যিক গ্রন্থাগার ব্যবহার করা হয়নি

আপনি ফাইলের সামগ্রী থেকে একটি নতুন স্ট্রিং অবজেক্ট তৈরি করতে পারেন ( java.nio.fileপ্যাকেজ থেকে ক্লাস ব্যবহার করে ):

public String readStringFromFile(String filePath) throws IOException {
    String fileContent = new String(Files.readAllBytes(Paths.get(filePath)));
    return fileContent;
}

মরিৎজ পিটারসেন উত্তরের সদৃশ কে লিখেছেন: স্ট্রিং সামগ্রী = নতুন স্ট্রিং (ফাইলস.রেডআলবাইটস (পাথস.জেট (ফাইলের নাম)), "ইউটিএফ -8");
জিন-ক্রিস্টোফ ব্লানচার্ড

8

একই থিমটিতে একটি প্রকরণ রয়েছে যা লাইন ভেরিয়েবলের পরিধি সীমাবদ্ধ করার জন্য কিছুক্ষণ লুপের পরিবর্তে লুপের জন্য ব্যবহার করে। এটি "আরও ভাল" তা ব্যক্তিগত স্বাদের বিষয়।

for(String line = reader.readLine(); line != null; line = reader.readLine()) {
    stringBuilder.append(line);
    stringBuilder.append(ls);
}

3
এটি নিউলাইনগুলিকে ডিফল্ট নিউলাইন choise এ পরিবর্তন করবে। এটি পছন্দসই বা অযৌক্তিক হতে পারে।
পিটার লরি

এই উত্তরে সম্পাদনাটি ঘুরিয়ে দেওয়া হয়েছে কারণ পয়েন্টটি ছিল lineভেরিয়েবলের পরিধি সঙ্কুচিত করা । সম্পাদনাটি এটি দু'বার ঘোষণা করেছে, যা একটি সংকলন ত্রুটি হবে।
ড্যান ডায়ার

7

আপনার যদি Filesক্লাসে অ্যাক্সেস না থাকে তবে আপনি একটি স্থানীয় সমাধান ব্যবহার করতে পারেন।

static String readFile(File file, String charset)
        throws IOException
{
    FileInputStream fileInputStream = new FileInputStream(file);
    byte[] buffer = new byte[fileInputStream.available()];
    int length = fileInputStream.read(buffer);
    fileInputStream.close();
    return new String(buffer, 0, length, charset);
}

উদাহরণস্বরূপ প্রার্থনা?
থুফির

4

একটি নমনীয় সলিউশন ব্যবহার IOUtils অ্যাপাচি থেকে Commons-IO সঙ্গে একযোগে StringWriter :

Reader input = new FileReader();
StringWriter output = new StringWriter();
try {
  IOUtils.copy(input, output);
} finally {
  input.close();
}
String fileContents = output.toString();

এটি কোনও পাঠক বা ইনপুট স্ট্রিমের সাথে কাজ করে (কেবল ফাইলগুলির সাথে নয়), উদাহরণস্বরূপ কোনও ইউআরএল থেকে পড়ার সময়।


3

fileInputStream.available()প্রত্যাশিত পূর্ণসংখ্যার ব্যবহার করার সময় সচেতন থাকুন প্রকৃত ফাইল আকারটি উপস্থাপন করতে হবে না, বরং IO কে অবরুদ্ধ না করে সিস্টেমটি অনুমান করা পরিমাণ বাইটগুলি স্ট্রিম থেকে পড়তে সক্ষম হবে। একটি নিরাপদ এবং সহজ উপায় এর মত দেখতে পারে

public String readStringFromInputStream(FileInputStream fileInputStream) {
    StringBuffer stringBuffer = new StringBuffer();
    try {
        byte[] buffer;
        while (fileInputStream.available() > 0) {
            buffer = new byte[fileInputStream.available()];
            fileInputStream.read(buffer);
            stringBuffer.append(new String(buffer, "ISO-8859-1"));
        }
    } catch (FileNotFoundException e) {
    } catch (IOException e) { }
    return stringBuffer.toString();
}

এটি বিবেচনা করা উচিত যে এই পদ্ধতিটি ইউটিএফ -8 এর মতো মাল্টি-বাইট অক্ষর এনকোডিংগুলির জন্য উপযুক্ত নয়


1
এই কোডটি প্রত্যাশিত ফলাফল দিতে পারে। মতে ডকুমেন্টেশন এর available()পদ্ধতি, যে কোন গ্যারান্টি ফাইলের শেষে যে পদ্ধতি ফেরৎ 0. যে ক্ষেত্রে আপনি একটি অসম্পূর্ণ ফাইল দিয়ে শেষ পারে ইভেন্টে উপনিত হয়। সবচেয়ে খারাপটি, আসলে পড়া বাইটের সংখ্যা যে ফেরত দেওয়া মানের চেয়ে কম হতে পারে, সেক্ষেত্রে available()আপনি দূষিত আউটপুট পান।
ওয়াও

3

এইটি পদ্ধতিটি ব্যবহার করে RandomAccessFile.readFully, এটি জেডিকে ১.০ থেকে উপলব্ধ বলে মনে হচ্ছে!

public static String readFileContent(String filename, Charset charset) throws IOException {
    RandomAccessFile raf = null;
    try {
        raf = new RandomAccessFile(filename, "r");
        byte[] buffer = new byte[(int)raf.length()];
        raf.readFully(buffer);
        return new String(buffer, charset);
    } finally {
        closeStream(raf);
    }
} 


private static void closeStream(Closeable c) {
    if (c != null) {
        try {
            c.close();
        } catch (IOException ex) {
            // do nothing
        }
    }
}

3

আপনি স্ক্যানার এবং ফাইল ক্লাস চেষ্টা করতে পারেন, কয়েকটি লাইন সমাধান

 try
{
  String content = new Scanner(new File("file.txt")).useDelimiter("\\Z").next();
  System.out.println(content);
}
catch(FileNotFoundException e)
{
  System.out.println("not found!");
}

3

ব্যবহারকারী java.nio.Filesফাইলের সমস্ত লাইন পড়তে পারেন।

public String readFile() throws IOException {
        File fileToRead = new File("file path");
        List<String> fileLines = Files.readAllLines(fileToRead.toPath());
        return StringUtils.join(fileLines, StringUtils.EMPTY);
}

3
public static String slurp (final File file)
throws IOException {
    StringBuilder result = new StringBuilder();

    BufferedReader reader = new BufferedReader(new FileReader(file));

    try {
        char[] buf = new char[1024];

        int r = 0;

        while ((r = reader.read(buf)) != -1) {
            result.append(buf, 0, r);
        }
    }
    finally {
        reader.close();
    }

    return result.toString();
}

আমি মনে করি প্ল্যাটফর্মের ডিফল্ট এনকোডিংটি ব্যবহার করে এতে অসুবিধে ওএস রয়েছে। যাইহোক +1 :)
অস্কাররেজ

7
আমার কাছে মনে হচ্ছে অবশেষে ব্লকটি চেষ্টা ব্লকে সংজ্ঞায়িত ভেরিয়েবলগুলি জানে না। জাভ্যাক 1.6.0_21 ত্রুটিটি ছুড়ে ফেলে cannot find symbol
16.111

আপনি কি নিজের কোডটি চেষ্টা করেছেন? আপনি পাঠককে চেষ্টা / ক্যাচ ব্লকে সংজ্ঞায়িত করেছেন, তাই এটি অবশেষে ব্লকে অ্যাক্সেসযোগ্য হবে না।
mauron85

2

আমি অন্যান্য এন্ট্রিগুলিতে এখনও মন্তব্য করতে পারি না, তাই আমি এটি এখানে রেখে দেব।

এখানে সেরা উত্তরগুলির মধ্যে একটি ( https://stackoverflow.com/a/326448/1521167 ):

private String readFile(String pathname) throws IOException {

File file = new File(pathname);
StringBuilder fileContents = new StringBuilder((int)file.length());
Scanner scanner = new Scanner(file);
String lineSeparator = System.getProperty("line.separator");

try {
    while(scanner.hasNextLine()) {        
        fileContents.append(scanner.nextLine() + lineSeparator);
    }
    return fileContents.toString();
} finally {
    scanner.close();
}
}

এখনও একটি ত্রুটি আছে। এটি স্ট্রিংয়ের শেষে সর্বদা নতুন লাইন চর স্থাপন করে, যার ফলে কিছু অদ্ভুত ত্রুটি হতে পারে। আমার পরামর্শটি এটিকে পরিবর্তন করতে হবে:

    private String readFile(String pathname) throws IOException {
    File file = new File(pathname);
    StringBuilder fileContents = new StringBuilder((int) file.length());
    Scanner scanner = new Scanner(new BufferedReader(new FileReader(file)));
    String lineSeparator = System.getProperty("line.separator");

    try {
        if (scanner.hasNextLine()) {
            fileContents.append(scanner.nextLine());
        }
        while (scanner.hasNextLine()) {
            fileContents.append(lineSeparator + scanner.nextLine());
        }
        return fileContents.toString();
    } finally {
        scanner.close();
    }
}

প্রথম ক্ষেত্রে আপনি শেষে একটি অতিরিক্ত নিউলাইন যোগ করা হতে পারে। দ্বিতীয় ক্ষেত্রে আপনি একটি বাদ দিতে পারে। সুতরাং উভয়ই সমানভাবে ভুল। এই নিবন্ধটি
প্যাট্রিক পার্কার

2

স্ক্যানারের পরে Ctrl + F'ing করার পরে, আমি মনে করি যে স্ক্যানার সমাধানটিও তালিকাভুক্ত করা উচিত। ফ্যাশন পড়ার সবচেয়ে সহজতে এটি এরকম হয়:

public String fileToString(File file, Charset charset) {
  Scanner fileReader = new Scanner(file, charset);
  fileReader.useDelimiter("\\Z"); // \Z means EOF.
  String out = fileReader.next();
  fileReader.close();
  return out;
}

আপনি যদি জাভা 7 বা আরও নতুন ব্যবহার করেন (এবং আপনার সত্যিকারের উচিত) কোডটি পড়া সহজতর করার জন্য রিসোর্স-সহ ব্যবহার করার বিষয়টি বিবেচনা করুন। সবকিছু ছড়িয়ে ছিটিয়ে থাকা আর কোনও বিন্দু-ঘনিষ্ঠ স্টাফ নেই। তবে এটি বেশিরভাগই একটি স্টাইলিস্টিক পছন্দ মেথিনিক্স।

আমি এটি বেশিরভাগ সম্পূর্ণতার জন্য পোস্ট করছি, যেহেতু আপনার যদি এটি প্রচুর প্রয়োজন হয় তবে java.nio.file.Files এ জিনিসগুলি আরও ভাল করা উচিত।

আমার পরামর্শটি হ'ল সমস্ত বাইট দখল করার জন্য ফাইল # রিডআলবাইটস (পাথ) ব্যবহার করা এবং এটির একটি স্ট্রিং যাতে আপনি বিশ্বাস করতে পারেন তা পেতে এটি নতুন স্ট্রিং (বাইট [] চারসেট) এ খাওয়ান । চরসেটগুলি আপনার জীবদ্দশায় আপনার কাছে অর্থ হবে, সুতরাং এখন এই জিনিসগুলি থেকে সাবধান থাকুন।

অন্যরা কোড এবং স্টাফ দিয়েছে এবং আমি তাদের গৌরব চুরি করতে চাই না। ;)



2

এছাড়াও যদি আপনার ফাইলটি কোনও জারের ভিতরে থাকে তবে আপনি এটি ব্যবহার করতে পারেন:

public String fromFileInJar(String path) {
    try ( Scanner scanner 
            = new Scanner(getClass().getResourceAsStream(path))) {
        return scanner.useDelimiter("\\A").next();
    }
}

/ উদাহরণস্বরূপ আপনার জারটি থাকলে পথটি শুরু করা উচিত

my.jar/com/some/thing/a.txt

তারপরে আপনি এটিকে এভাবে চালিত করতে চান:

String myTxt = fromFileInJar("/com/com/thing/a.txt");


2

@ এরিকসনের উত্তরের ভিত্তিতে আপনি ব্যবহার করতে পারেন:

public String readAll(String fileName) throws IOException {
    List<String> lines = Files.readAllLines(new File(fileName).toPath());
    return String.join("\n", lines.toArray(new String[lines.size()]));
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.