摘要:除非文件用自帶的記事本打開我們能夠讀懂,才采用字符流,否則建議使用字節(jié)流。
第四階段 IO IO流 前言:
前面的學習我們只能夠在已有的一定封閉范圍內(nèi)進行一些操作,但是這顯然是無趣的,也是不支持我們實現(xiàn)一些復雜的需求,所以Java提供IO流這樣一種概念,方便我們對數(shù)據(jù)進行操作
而使用IO流我們可以實現(xiàn)一些強大的功能,例如針對文件的移動復制等操作,又或者程序與外部文件之間的數(shù)據(jù)存儲或者讀取,又或者實現(xiàn)一個實時的聊天程序(網(wǎng)絡編程),其中數(shù)據(jù)的傳輸也用到了我們的IO流,這些內(nèi)容我們都會在后面設計,下面我就開始IO流的正式學習
(一) IO流的概述及分類 (1) 概念IO 即 input/output(輸入/輸出),流的概念還是有一些陌生的
“流”從字面看來就是類似水流的概念,其具有方向性,流動性,連續(xù)性、并且可以承載一些事物,而在我們計算機中,“流”是對一種有序連續(xù)具有方向性的數(shù)據(jù)的抽象描述。其本質(zhì)就是數(shù)據(jù)的傳輸,而根據(jù)其特點將其抽象封裝為各種類,更加方便了用戶的操作
(2) 分類A:流向
輸入流——讀取數(shù)據(jù)
輸出流——寫出數(shù)據(jù)
B:數(shù)據(jù)類型
字節(jié)流
字節(jié)輸入流——InputStream
字節(jié)輸出流——OutputStream
字符流
字符輸入流——Reader
字符輸出流——Writer
注意:
a: 如果我們沒有明確說明按照什么分,默認按照數(shù)據(jù)類型分。
b: 除非文件用windows自帶的記事本打開我們能夠讀懂,才采用字符流,否則建議使用字節(jié)流。
(二) 字節(jié)流 (1) FileOutputStream 寫出數(shù)據(jù)A:操作步驟
創(chuàng)建字節(jié)輸出流對象
調(diào)用writer()方法
釋放資源
B:代碼體現(xiàn)
FileOutputStream fos = new FileOutputStream("fos.txt"); for.write("hello".getBytes()); fos.close;
換行操作
因為不同的系統(tǒng)針對不同的換行符號識別是不一樣的
windows:rn linux:n Mac:r
而一些常見的高級記事本是可以識別任意換行符號的
如何實現(xiàn)數(shù)據(jù)的追加寫入 ?
用構造方法帶第二個參數(shù)是true的情況即可
FileOutputStream?fos?=?new?FileOutputStream("fos.txt",?true);(2) FileInputStream 讀取數(shù)據(jù)
A:操作步驟
創(chuàng)建字節(jié)輸入流對象
調(diào)用writer()方法
釋放資源
B:代碼體現(xiàn)
FileInputStream fis = new FileInputStream("fos.txt");
//使用FileInputStream對指定路徑下內(nèi)容進行讀取,可以結合FileOutputStream實現(xiàn)對文件的操作 import java.io.FileInputStream; import java.io.IOException; public class FileInputStreamDemo { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("F:fos.txt"); //方式一 int by = 0; while ((by = fis.read()) != -1){ System.out.print((char)by); } //方式二(這種方式更加快,推薦) //數(shù)組長度一般是1024或者1024的整數(shù)倍 byte[] bys = new byte[1024]; int len = 0; while((len = fis.read(bys))!=-1){ System.out.print(new String(bys,0,len)); } //釋放資源 fis.close(); } }(3) 字節(jié)緩沖流
//統(tǒng)計這段程序運行時間 long start = System.currentTimeMillis(); //受測試代碼 long end = System.currentTimeMillis(); System.out.println("共耗時" + (end - start) + "毫秒");
字節(jié)流一次讀寫一個數(shù)組的速度明顯比一次讀寫一個字節(jié)的速度快很多,這是加入了數(shù)組這樣的緩沖區(qū)效果,java本身在設計的時候,也考慮到了這樣的設計思想(裝飾設計模式后面講解),所以提供了字節(jié)緩沖區(qū)流
//字節(jié)緩沖輸出流 BuffereOutputStream //字節(jié)緩沖輸入流 BufferedInputStream
import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; public class BufferedOutputStreamDemo { public static void main(String[] args) throws IOException { // FileOutputStream fos = new FileOutputStream("F:fos.txt"); // BufferedOutputStream bos = new BufferedOutputStream(fos); //簡單寫法 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("F:fos.txt")); //寫數(shù)據(jù) bos.write("hello".getBytes()); //釋放資源,注意不需要fos.close bos.close(); } }
為什么不傳遞一個具體的文件或者文件路徑,而是傳遞一個OutputStream對象呢?
原因很簡單,字節(jié)緩沖區(qū)流僅僅提供緩沖區(qū),為高效而設計的。但是呢,真正的讀寫操作還得靠基本的流對象實現(xiàn)。
import java.io.*; public class Test { public static void main(String[] args) throws IOException { long start = System.currentTimeMillis(); method1("E:夜曲.mp3", "F:Test1.mp3"); method2("E:夜曲.mp3", "F:Test2.mp3"); method3("E:夜曲.mp3", "F:Test3.mp3"); method4("E:夜曲.mp3", "F:Test4.mp3"); long end = System.currentTimeMillis(); System.out.println("共耗時" + (end - start) + "毫秒"); } //基本字節(jié)流一次讀寫一個字符 public static void method1(String srcString, String deskString) throws IOException { FileInputStream fis = new FileInputStream(srcString); FileOutputStream fos = new FileOutputStream(deskString); int by = 0; while ((by = fis.read()) != -1) { fos.write(by); } fis.close(); fos.close(); } //基本字節(jié)流一次讀寫一個字節(jié)數(shù)組 public static void method2(String srcString, String deskString) throws IOException { FileInputStream fis = new FileInputStream(srcString); FileOutputStream fos = new FileOutputStream(deskString); byte[] bys = new byte[1024]; int len = 0; while ((len = fis.read(bys)) != -1) { fos.write(bys, 0, len); } fis.close(); fos.close(); } //高效字節(jié)流一次讀寫一個字節(jié) public static void method3(String srcString, String deskString) throws IOException { BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcString)); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(deskString)); int by = 0; while ((by = bis.read()) != -1) { bos.write(by); } bis.close(); bos.close(); } //高效字節(jié)流一次讀寫一個字節(jié)數(shù)組 public static void method4(String srcString, String deskString) throws IOException { BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcString)); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(deskString)); byte[] bys = new byte[1024]; int len = 0; while ((len = bis.read(bys)) != -1) { bos.write(bys, 0, len); } } } //運行結果 共耗時125961毫秒 共耗時143毫秒 共耗時1356毫秒 共耗時29毫秒
由此可見在上述四種方式中,效率最高的還是最后一種——高效字節(jié)流一次讀寫一個字節(jié)數(shù)組!
(三) 字符流我們在開發(fā)中,如果想要對我們所能識別的文本內(nèi)容進行數(shù)據(jù)的傳輸,如果我們繼續(xù)使用我們上面所學習的字節(jié)流,我們就會發(fā)現(xiàn)顯示出來的內(nèi)容是亂碼,這是因為編碼出現(xiàn)了問題,而這個時候我們就會用到我們的字符流,我們可以先簡單的認識 字符流 = 字節(jié)流 + 編碼(1) 編碼解碼
編碼 | 說明 |
---|---|
ASCII | 美國標準信息交換碼,用一個字節(jié)的7位可以表示。 |
ISO8859-1 | 拉丁碼表。歐洲碼表,用一個字節(jié)的8位表示。 |
GB2312 | 中國的中文編碼表。 |
GBK | 中國的中文編碼表升級,融合了更多的中文文字符號。 |
GB18030 | GBK的取代版本 |
BIG-5碼 | 行于臺灣、香港地區(qū)的一個繁體字編碼方案,俗稱“大五碼”。 |
Unicode | 國際標準碼,融合了多種文字, 有文字都用兩個字節(jié)來表示,Java語言使用的就是unicode |
UTF-8 | 最多用三個字節(jié)來表示一個字符。UTF-8不同,它定義了一種“區(qū)間規(guī)則”,這種規(guī)則可以和ASCII編碼保持最大程度的兼容:它將Unicode編碼為00000000-0000007F的字符,用單個字節(jié)來表示它將Unicode編碼為00000080-000007FF的字符用兩個字節(jié)表示 它將Unicode編碼為00000800-0000FFFF的字符用3字節(jié)表示 |
字節(jié)流我們前面已經(jīng)有了一定的認識,那么什么是編碼和解碼呢?
編碼是信息從一種形式或格式轉(zhuǎn)換為另一種形式的過程;解碼則是編碼的逆過程。
我們先通過一個例子來了解一下它的流程
//通過指定的字符集解碼字節(jié)數(shù)組 String(byte[]?bytes,?String?charsetName) //使用指定的字符集合把字符串編碼為字節(jié)數(shù)組 byte[]?getBytes(String?charsetName)
import java.io.UnsupportedEncodingException; import java.util.Arrays; public class EncodingDemo { public static void main(String[] args) throws UnsupportedEncodingException { String s = "理想"; //String - byte[] - 編碼 byte[] bys = s.getBytes(); //[-25, -112, -122, -26, -125, -77] // byte[] bys = s.getBytes("UTF-8"); //[-25, -112, -122, -26, -125, -77] // byte[] bys = s.getBytes("GBK"); //[-64, -19, -49, -21] System.out.println(Arrays.toString(bys)); //byte[] - String - 解碼 String string = new String(bys); //理想 // String string = new String(bys,"UTF-8"); //理想 // String string = new String(bys,"GBK"); //鐞嗘兂 System.out.println(string); } }
發(fā)送過程:“理想” —— 數(shù)字 —— 二進制 —— 發(fā)送
接收過程:接收 —— 二進制 —— 十進制 —— 數(shù)值 —— 字符 —— “理想”
其實簡單的總結就是:
編碼:把看得懂的變成看不懂的
解碼:把看不懂的變成看得懂的
(2) 字符輸入輸出流OutputStreamWriter 字符輸出流(寫出)
public OutputStreamWriter(OutputStream out) public OutputStreamWriter(OutputStream out,String charsetName)
InputStreamReader 字符輸入流(讀取)
public InputStreamReader(InputStream in) public InputStreamReader(InputStream in,String charsetName)
OutputStreamWriter寫數(shù)據(jù)方法
//寫一個字符 public void write(int c) //寫一個字符數(shù)組 public void write(char[] cbuf) //寫一個字符數(shù)組的一部分 public void write(char[] cbuf,int off,int len) //寫一個字符串 public void write(String str) //寫一個字符串的一部分 public void write(String str,int off,int len)
OutputStreamWriter讀數(shù)據(jù)方法
//讀一個字符 public int read() //第一個字符數(shù)組 public int read(char[] cbuf)
字符流操作要注意的問題
flush()和close()的區(qū)別 ?
close:關閉流對象,但是先刷新一次緩沖區(qū),關閉之后,流對象就不能繼續(xù)使用了
flush:僅僅刷新緩沖區(qū),刷新之后,流對象還可以繼續(xù)使用
(2) 字符流的簡單寫法轉(zhuǎn)換流的名字比較長,而我們常見的操作都是按照本地默認編碼實現(xiàn)的,所以,為了簡化我們的書寫,轉(zhuǎn)換流提供了對應的子類
//輸出流 FileWriter //輸入流 FileReader
OutputStreamWriter?osw?= new?OutputStreamWriter(new?FileOutputStream("b.txt")) //等價 FileWriter?fw?=?new?FileWriter("b.txt"); (寫出) InputStreamReader?isr?=?new?InputStreamReader(new?FileInputStream("a.txt")) //等價? FileReader?fr?=?new?FileReader("a.txt"); (讀取)(3) 字符緩沖流
?BufferedWriter:字符緩沖輸出流
將文本寫入字符輸出流,緩沖各個字符,從而提供單個字符、數(shù)組和字符串的高效寫入。
可以指定緩沖區(qū)的大小,或者接受默認的大小。在大多數(shù)情況下,默認值就足夠大了。
BufferedReader:字符緩沖輸入流
從字符輸入流中讀取文本,緩沖各個字符,從而實現(xiàn)字符、數(shù)組和行的高效讀取。
可以指定緩沖區(qū)的大小,或者可使用默認的大小。大多數(shù)情況下,默認值就足夠大了。
特殊功能
BufferedWriter:
//根據(jù)系統(tǒng)來決定換行符 public?void?newLine()
BufferedReader:
//一次讀取一行數(shù)據(jù),包含該行內(nèi)容的字符串,不包含任何行終止符,如果已到達流末尾,則返回?null public?String?readLine()(四) IO流案例 字節(jié)流案例
案例一:復制單級文件夾
import java.io.*; /* * 需求:復制單級文件夾 * * 數(shù)據(jù)源:f:demo * 目的地:f: est * * 分析: * A:封裝目錄 * B:獲取該目錄下的所有文本的File數(shù)組 * C:遍歷該File數(shù)組,得到每一個File對象 * D:把該File進行復制 */ public class CopyFolderDemo { public static void main(String[] args) throws IOException { File srcFloder = new File("F:demo"); File deskFloder = new File("F: est"); if (!deskFloder.exists()) { deskFloder.mkdirs(); } File[] fileArray = srcFloder.listFiles(); for (File file : fileArray) { String name = file.getName(); //拼湊出每一個文件的路徑 File newFile = new File(deskFloder, name); copyFloder(file, newFile); } } public static void copyFloder(File file, File newFile) throws IOException { BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newFile)); byte[] bys = new byte[1024]; int len = 0; while ((len = bis.read()) != -1) { bos.write(bys, 0, len); } bis.close(); bos.close(); } }
案例二:復制指定目錄下的指定文件,并修改后綴名
import java.io.*; /* * 需求:復制指定目錄下的指定文件,并修改后綴名。 * 指定的文件是:.txt文件。 * 指定的后綴名是:.bat * 指定的目錄是:test * * 數(shù)據(jù)源:f:demoA.txt * 目的地:f: estA.bat * * 分析: * A:封裝目錄 * B:獲取該目錄下的java文件的File數(shù)組 * C:遍歷該File數(shù)組,得到每一個File對象 * D:把該File進行復制 * E:在目的地目錄下改名 */ public class CopyFolderDemo2 { public static void main(String[] args) throws IOException { File srcFloder = new File("F:demo"); File destFloder = new File("F: est"); if (!destFloder.exists()) { destFloder.mkdirs(); } File[] fileArray = srcFloder.listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String name) { return new File(dir, name).isFile() && name.endsWith(".txt"); } }); for (File file : fileArray) { String name = file.getName(); File newFile = new File(destFloder, name); copyFile(file, newFile); } File[] deskFileArray = destFloder.listFiles(); for (File destFile : deskFileArray) { String name = destFile.getName(); String newName = name.replace(".txt", ".bat"); File newFile = new File(destFloder, newName); destFile.renameTo(newFile); } } public static void copyFile(File file, File newFile) throws IOException { BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newFile)); byte[] bys = new byte[1024]; int len = 0; while ((len = bis.read(bys)) != -1) { bos.write(bys, 0, len); } bis.close(); bos.close(); } }
案例三:復制多級文件夾
import java.io.*; /* * 需求:復制多極文件夾 * * 數(shù)據(jù)源:F:admin * 目的地:E: * * 分析: * A:封裝數(shù)據(jù)源File * B:封裝目的地File * C:判斷該File是文件夾還是文件 * a:是文件夾 * 就在目的地目錄下創(chuàng)建該文件夾 * 獲取該File對象下的所有文件或者文件夾File對象 * 遍歷得到每一個File對象 * 回到C * b:是文件 * 就復制(字節(jié)流) */ public class CopyFloderDemo3 { public static void main(String[] args) throws IOException { File srcFile = new File("F:admin"); File destFile = new File("E:"); copyFolder(srcFile, destFile); } private static void copyFolder(File srcFile, File destFile) throws IOException { if (srcFile.isDirectory()) { File newFolder = new File(destFile, srcFile.getName()); newFolder.mkdirs(); //獲取該File對象下的所有文件或者文件夾File對象 File[] fileArray = srcFile.listFiles(); for (File file : fileArray) { //遞歸,繼續(xù)判斷 copyFolder(file, newFolder); } } else { File newFile = new File(destFile, srcFile.getName()); copyFile(srcFile, newFile); } } private static void copyFile(File srcFile, File newFile) throws IOException { BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile)); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newFile)); byte[] bys = new byte[1024]; int len = 0; while ((len = bis.read(bys)) != -1) { bos.write(bys, 0, len); } bos.close(); bis.close(); } }字符流案例
案例一:隨機獲取文本文件中的姓名案例
import java.io.*; import java.util.ArrayList; import java.util.Random; /* * 隨機獲取文本文件中的姓名案例 * 需求:我有一個文本文件中存儲了幾個名稱 * 請大家寫一個程序?qū)崿F(xiàn)隨機獲取一個人的名字。 * * 分析: * A:把文本文件中的數(shù)據(jù)存儲到集合中 * B:隨機產(chǎn)生一個索引 * C:根據(jù)該索引獲取一個值 */ public class GetRandName { public static void main(String[] args) throws IOException { String path = "F: est.txt"; // BufferedReader br = new BufferedReader(new FileReader(path)); //默認記事本以ansi編碼保存,但是使用FileReader默認使用UTF-8輸出,所以使用上面語句會亂碼 BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(path), "gb2312")); ArrayListarray = new ArrayList<>(); String line = null; while ((line = br.readLine()) != null) { array.add(line); } br.close(); Random r = new Random(); int index = r.nextInt(array.size()); String name = array.get(index); System.out.println("該幸運兒是:" + name); } }
案例二:鍵盤錄入學生信息按照總分排序并寫入文本文件案例
//Student類自行補充 import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.util.Comparator; import java.util.Scanner; import java.util.TreeSet; public class StudentDemo { public static void main(String[] args) throws IOException { TreeSetts = new TreeSet (new Comparator () { @Override public int compare(Student s1, Student s2) { int num = s2.getSum() - s1.getSum(); int num2 = num == 0 ? s1.getChinese() - s2.getChinese() : num; int num3 = num2 == 0 ? s1.getMath() - s2.getMath() : num2; int num4 = num3 == 0 ? s1.getEnglish() - s2.getEnglish() : num3; int num5 = num4 == 0 ? s1.getName().compareTo(s2.getName()) : num4; return num5; } }); for (int x = 1; x <= 3; x++) { Scanner sc = new Scanner(System.in); System.out.println("請輸入第" + x + "個學生成績信息"); System.out.println("姓名:"); String name = sc.nextLine(); System.out.println("語文成績:"); int chinese = sc.nextInt(); System.out.println("數(shù)學成績:"); int math = sc.nextInt(); System.out.println("英語成績:"); int english = sc.nextInt(); Student s = new Student(); s.setName(name); s.setChinese(chinese); s.setMath(math); s.setEnglish(english); ts.add(s); BufferedWriter bw = new BufferedWriter(new FileWriter("F:students.txt")); bw.write("學生成績信息如下"); bw.newLine(); bw.flush(); bw.write("姓名-語文成績-數(shù)學成績-英語成績"); bw.newLine(); bw.flush(); for (Student stu : ts) { StringBuilder sb = new StringBuilder(); sb.append(stu.getName() + "-" + stu.getChinese() + "-" + stu.getMath() + "-" + stu.getEnglish()); bw.write(sb.toString()); bw.newLine(); bw.flush(); } bw.close(); System.out.println("學生成績信息錄入完畢"); } } }
案例三:登陸注冊案例(使用IO)
在前幾篇中集合實現(xiàn)的基礎上,其余文件不變,只需要對 UserDaoImpl.java 文件進行重寫
由于篇幅較長,其余dao、pojo、test層代碼請翻閱前幾篇中 集合框架——List篇
package cn.bwh_05_LoginDemo.dao.impl; import cn.bwh_05_LoginDemo.dao.UserDao; import cn.bwh_05_LoginDemo.pojo.User; import java.io.*; /** * 這是用戶操作的具體實現(xiàn)類 (IO) * * @author BWH_Steven * @version v1.1 */ public class UserDaoImpl implements UserDao { private static File file = new File("User.txt"); static { try { file.createNewFile(); } catch (IOException e) { System.out.println("創(chuàng)建文件失敗"); e.printStackTrace(); } } @Override public boolean isLogin(String username, String password) { boolean flag = false; BufferedReader br = null; String path = "user.txt"; try { br = new BufferedReader(new FileReader(file)); String line = null; while ((line = br.readLine()) != null) { //用戶名--密碼 String[] datas = line.split("--"); if (datas[0].equals(username) && datas[1].equals(password)) { flag = true; break; } } } catch (FileNotFoundException e) { System.out.println("找不到登錄所需要的信息文件"); e.printStackTrace(); } catch (IOException e) { System.out.println("用戶登錄失敗"); e.printStackTrace(); } finally { if (br != null) { try { br.close(); } catch (IOException e) { System.out.println("用戶登錄釋放資源失敗"); e.printStackTrace(); } } } return flag; } @Override public void regist(User user) { /* * 為注冊的數(shù)據(jù)定義一個規(guī)則: 用戶名--密碼 */ BufferedWriter bw = null; String path = "user.txt"; try { //為了保證數(shù)據(jù)是追加寫入,所以必須加true bw = new BufferedWriter(new FileWriter(file, true)); //bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path,true),"gb2312")); bw.write(user.getUsername() + "--" + user.getPassword()); bw.newLine(); bw.flush(); } catch (IOException e) { System.out.println("用戶注冊失敗"); e.printStackTrace(); } finally { try { bw.close(); } catch (IOException e) { System.out.println("用戶注冊釋放資源失敗"); e.printStackTrace(); } } } }結尾:
如果內(nèi)容中有什么不足,或者錯誤的地方,歡迎大家給我留言提出意見, 蟹蟹大家 !^_^
如果能幫到你的話,那就來關注我吧!(系列文章均會在公眾號第一時間更新)
在這里的我們素不相識,卻都在為了自己的夢而努力 ?一個堅持推送原創(chuàng)Java技術的公眾號:理想二旬不止
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/75327.html
摘要:流做下載等功能時候,我們經(jīng)常會使用數(shù)據(jù)流模塊,因為,在大文件下載場景下,如果使用接口將文件全部讀入內(nèi)存然后再返回給客戶端,很容易撐爆內(nèi)存,比如一個文件,同時有人在下載,那么服務就需要占用內(nèi)存。 NPM酷庫,每天兩分鐘,了解一個流行NPM庫。 流 做下載等功能時候,我們經(jīng)常會使用數(shù)據(jù)流模塊(stream),因為,在大文件下載場景下,如果使用fs.readFile()接口將文件全部讀入內(nèi)存...
摘要:本教程將演示通過云直播服務,快速發(fā)起一場支持萬人觀看的直播。一個完成實名認證的賬號。體驗金到賬后,選擇購買流量,彈框內(nèi)選擇流量包大小,點擊確認,立即支付,即可完成購買。至此,云直播的配置已經(jīng)完成,下一篇教程指導如何利用工具發(fā)起觀看直播。本教程將演示通過ULive云直播服務,快速發(fā)起一場支持萬人觀看的直播。直播前需要準備的工具:推流工具OBS 下載地址:測試播放器:下載地址一個完成ICP備案的...
摘要:選擇網(wǎng)絡,將完整的播放地址粘貼進去,點擊串流一直,最后點擊流,即可觀看直播。本教程主要指導大家如何通過快速的發(fā)起一場直播,后續(xù)將為大家介紹視頻轉(zhuǎn)碼截圖錄制存儲等直播中常用增值功能的使用。上文介紹了在UCloud如何配置直播推拉流,獲取推流和拉流的完整地址,下面將指導大家開啟和觀看直播。開始直播1、打開OBS推流軟件(安裝過程一直next即可,本文不再贅述),來源點擊+號,即可使用OBS捕獲任...
摘要:通過集成,可以從零開始,快速搭建出實時音視頻通信平臺,可以應用于語音和視頻社交在線教育和培訓遠程醫(yī)療在線會議直播等多種業(yè)務場景。集成之前,需要在官網(wǎng)控制臺創(chuàng)建應用。使用服務之前,首先需要注冊賬號并且完成實名認證。確定后,自動生成。通過集成URTC SDK,可以從零開始,快速搭建出實時音視頻通信平臺,可以應用于語音和視頻社交、在線教育和培訓、遠程醫(yī)療、在線會議、直播等多種業(yè)務場景。 集成URT...
閱讀 3267·2021-11-22 14:44
閱讀 1112·2021-11-16 11:53
閱讀 1264·2021-11-12 10:36
閱讀 698·2021-10-14 09:43
閱讀 3684·2019-08-30 15:55
閱讀 3398·2019-08-30 14:14
閱讀 1733·2019-08-26 18:37
閱讀 3409·2019-08-26 12:12